4

I want to specialize a template for STL's vector template arguments. Something like this:

// (1)
template <typename T>
class A
{
    ...
};

// (2)
template <>
class A<std::vector<> >
{
    ...
};

I don't care what is the type of the vector element. I would like to use it as follows:

A<int> a1; // Will use the general specialization
A<std::vector<int> > a2; // Will use the second specialization

In general I've been trying to define something similar to boost's type traits. Something like

template <class T> 
struct is_stl_vector 
{
    // Will be true if T is a vector, false otherwise
    static const bool value = ...; 
};

I cannot use template template (I think so) because it should compile for non-template types too. Is it possible at all?

FireAphis
  • 6,650
  • 8
  • 42
  • 63
  • 3
    `std::vector` is from the C++ Standard Library, not the STL. – Lightness Races in Orbit Jan 18 '11 at 12:06
  • @Tomalak: What? `std::vector` is not from the STL? What is STL then? – Nawaz Jan 18 '11 at 12:10
  • @Tomalak: `std::vector` is included in the C++ Standard library as part of the [STL](http://en.wikipedia.org/wiki/Standard_Template_Library). So it is actually from both. – Antonio Pérez Jan 18 '11 at 12:11
  • 3
    No, @Antonio and @Nawaz. The term "STL" is misused by the C++ community. Strictly speaking, the STL is the original library. Parts of the C++ Standard Library were based on parts of the STL, but they are not one-and-the-same. It is true that, colloquially, people use the term "STL" to refer to those parts of the stdlib, but I feel it's important to know that they are indeed *not* the same. – Lightness Races in Orbit Jan 18 '11 at 12:17
  • 2
    @Nawaz: A library developed by Stepanov before the C++ language was standardised. *Parts* of the C++ standard library are very similar to it. Notably, nothing in the STL uses the `std` namespace. – Lightness Races in Orbit Jan 18 '11 at 12:18
  • 3
    And, yes, before you start, I know that there are books and resources that use the term to mean the standard library. – Lightness Races in Orbit Jan 18 '11 at 12:19
  • 7
    @Tomalak: can you think of a single reason *why* this is important? Or why it is at all relevant to *this* question? Plenty of people here know this, and just feel that trying to enforce this distinction is only causing confusion, and serves no purpose other than to prove that "I'm a more pedantic language lawyer than you". – jalf Jan 18 '11 at 12:27
  • 2
    @jalf: I spend much of my days assisting language newcomers. The slight differences in the two libraries *does* cause them confusion and thus *is* important, whether or not it's important to you! Also, clearly many people do *not* know this, as evidenced by the reaction to my original comment. Either way, I only meant it as an aside, which is why it's a comment. If we're not on StackOverflow to learn from each other then why else are we here? I'm content to have put across this information and now move on, rather than us arguing about whether or not you should care about it. – Lightness Races in Orbit Jan 18 '11 at 12:29
  • 2
    It's not in a comment, it's in 4 comments. It just seems excessive for what is such a pedantic and generally useless piece of trivia. I think everyone who knows it has gone through a phase of wanting to point out to the entire world that "they've got it wrong", but honestly, it just doesn't matter and in the end most of us just accept that "by default, people use STL to refer to the STL-derived portion of the stdlib. If they're not explicitly referring to the "original", assume they refer to the stdlib STL. It's generally clear from context "which" STL someone is talking about. – jalf Jan 18 '11 at 12:44
  • 1
    But feel free to point it out. You're technically correct, and if you feel it is important information, then go ahead (are you going to post these comments on *every* question related to the C++ standard libary?) – jalf Jan 18 '11 at 12:45
  • 2
    @Tomalak: It doesn't matter if originally STL didn't had `std` namespace, or was not included in Standard Library. But now, it's part of the C++ Standard Library. It's a subset of C++ Standard Library. And no, people don't use the term "STL" to refere to those parts of the ``. People use the term "STL" to refer to `std::vector`,`std::map`, `std::list`, etc. – Nawaz Jan 18 '11 at 12:47
  • 1
    @jalf: I suppose I shouldn't bring it up on *every* stdlib question. :) – Lightness Races in Orbit Jan 18 '11 at 15:30
  • @Nawaz: 'And no, people don't use the term "STL" to refere to those parts of the . People use the term "STL" to refer to std::vector,std::map, std::list, etc. ' Eh? That's what they are! @jalf: See? He's confused. Way to go, "STL"-promoters! – Lightness Races in Orbit Jan 18 '11 at 15:30
  • @Tomalak: is he? I agree his wording is unclear, but I don't see how that proves your point. On the contrary, there's no indication that anyone were confused about anything in this question before your comments. It was pretty clear from context that the OP was asking about the standard library vector, and not the SGI STL vector. The confusion arises as soon as someone tries to be pedantic, and brings the "old" STL into a discussion where it clearly had no relevance. – jalf Jan 18 '11 at 16:35
  • In a discussion about "Stepanovs STL" vs "the standard library STL", we obviously need to distinguish clearly between the two. But when people are just asking a question about some "STL" data structure or algorithm, it is a pretty safe bet to say that if no indication to the contrary is given, they are talking about the STL-derived parts of the standard library, and not Stepanov's original STL. And the best way to avoid confusion is really to roll with that, and temporarily forget about the "original" STL, rather than trying to correct the error. – jalf Jan 18 '11 at 16:37
  • 1
    @jalf Even though Nawaz just stated untrue assertions about the STL, there's no confusion? Just because you didn't know he had this fundamental misunderstanding before I brought it up, doesn't mean he didn't have it. – Lightness Races in Orbit Jan 18 '11 at 17:04
  • @jalf what @Nawaz says "People rightfully use STL to refer to random iterator / container / algorithm things in the Standard.". what @Tomalak says is "People wrongly use STL to refer to the parts of the original Stephanov STL that were placed into the stdlib and were subtly changed.". What I say is "People use STL to refer to the Standard Thread Library.". – Johannes Schaub - litb Jan 18 '11 at 17:27
  • @Tomalak: I'm not sure I see what "fundamental misunderstanding" he exhibits. I honestly can't make sense of the "And no, people don't use the term "STL" to refer to those parts of the ``" part. But that doesn't necessarily imply any kind of confusion on his part, but just a badly worded sentence written by someone who (I think) didn't have English as his first language. – jalf Jan 18 '11 at 20:58
  • I'm also not sure, even if this confusion exists, how it is relevant. It doesn't really matter to me if people are confused about the origin of the STL (that's an interesting piece of trivia, but it's not something you need to know in order to be a competent C++ programmer), as long as I can guess what they mean when they talk about a "STL vector", for example. And so far, in the question, answers and comments on this page, the only one who means something unexpected by that term is you. Everyone else is pretty predictable, and simply mean "the standard library vector" when they say it. – jalf Jan 18 '11 at 21:00
  • @jalf I'm sorry to hear that you don't get it, and that the plight of other people doesn't bother you in the slightest. I'm also sorry to see that you have completely ignored -- or otherwise misinterpreted -- Nawaz's last comment. I wish you the best of luck in the future. – Lightness Races in Orbit Jan 19 '11 at 02:39
  • @Tomalak: Wow, could you be any more condescending if you tried? I directly referred to his last comment just above. Like I said, most of it seems correct, except for one sentence I simply cannot make sense of. And here's the deal, everyone have a lot of confusion about a lot of things, *and that's ok*. I'm very confused about quantum mechanics, but it doesn't really pose a practical problem for me. Similarly, regardless of how confused some people may be about the origin of the STL, there's rarely any confusion about *what people mean when they say "STL" or "STL vector"*. – jalf Jan 19 '11 at 13:09
  • @jalf: Yes, I probably could. – Lightness Races in Orbit Jan 19 '11 at 13:58

2 Answers2

7

You can simply specialize like this:

// (2)
template <typename T, typename Alloc>
struct A<std::vector<T, Alloc> >
{...};
Grizzly
  • 19,595
  • 4
  • 60
  • 78
  • 2
    You'd get a +1 except that it's not this simple at all. See jpalecek's answer. – Lightness Races in Orbit Jan 18 '11 at 12:07
  • @Tomalak Geret'kal: actually I think there shouldn't be a problem with varying template parameter counts. That is because std::vector should use default template arguments, if there are any (this is different from using a template type in a template, where one would need the exact declaration). My compiler seems to agree with me by making this work even with template struct A >{...}. Of course it wouldn't match those vectors which use non default arguments for further template parameters, but those are likely rare. Please correct me if I'm wrong here. – Grizzly Jan 18 '11 at 12:13
  • @Tomalak: Actually, it is this simple. See my comment on jpalecek's answer. – Fred Nurk Jan 18 '11 at 12:46
  • @Grizzly: Oh, maybe. Have your +1 then. :) – Lightness Races in Orbit Jan 18 '11 at 15:29
  • @Tomalak what he says is not true. See http://stackoverflow.com/questions/1469743/standard-library-containers-with-additional-optional-template-parameters – Johannes Schaub - litb Jan 18 '11 at 17:38
  • @Johannes: And I believed him. :( Faith... shattered. -1! [edit: damn, I can't un-upvote until edited ;(] – Lightness Races in Orbit Jan 18 '11 at 20:33
6

The specialization goes like this:

// (2)
template <class T, class U>
class A<std::vector<T, U> >
{
    ...
};

Note that it is not guaranteed to work (and there si no other way that's guaranteed to work), because the template parameter count of std::vector may vary across implementations. In C++0x, this should be solvable using parameter packs.

jpalecek
  • 47,058
  • 7
  • 102
  • 144
  • It is precisely because user code can break that a conforming std::vector cannot have other than type and allocator template parameters, even if they have default values. However, I think you'd be very hard pressed to find an implementation where the above code fails. – Fred Nurk Jan 18 '11 at 12:50
  • @Fred Nurk: chapter and verse? Note that the same applies to regular functions as well: `float (*pSin)(float) = &std::sin` breaks when `float std::sin(float)` has extra defaulted arguments. – MSalters Jan 18 '11 at 13:29
  • @MSalters: C++03 §1.4p2 "If a program contains no violations of the rules in this International Standard, a conforming implementation shall, within its resource limits, accept and correctly execute that program." and §1.4p8 "A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any well-formed program." And yes, this applies to regular functions and, in fact, the whole stdlib. – Fred Nurk Jan 18 '11 at 13:50
  • One such well-formed, complete program: `#include template struct A; template struct A > {}; int main() {}` Plus the second sentence of §1.4p4 – if interpreted to apply to class templates, as it and the previous paragraph are somewhat vague – is more direct. – Fred Nurk Jan 18 '11 at 13:51
  • @MSalters: The restriction on not having more template parameters (even with default values; though this case doesn't apply to the code above), is very similar to functions with additional defaulted parameters: user code with templated template parameters (`template – Fred Nurk Jan 18 '11 at 13:56
  • That specialization is fine, even with additional implementation-specific default template parameters. The only times defaulted arguments need to be specified are the template's definition and forward declarations. – Steve M Jan 18 '11 at 14:54
  • @Fred Nurk: circular logic. See http://www.gotw.ca/gotw/064.htm . A program making faulty assumptions isn't covered by §1.4p2 and §1.4p8 – MSalters Jan 18 '11 at 16:39
  • 1
    @MSalters: §17.4.4.4p2 lists the specific exemption for methods so additional parameters may be declared; I see no exemption for class template parameters, and thus, that GotW doesn't apply here. – Fred Nurk Jan 18 '11 at 17:12
  • 3
    I think this answer is not true (last part). See http://stackoverflow.com/questions/1469743/standard-library-containers-with-additional-optional-template-parameters – Johannes Schaub - litb Jan 18 '11 at 17:38
  • @Johannes: are you saying that your own answer "The books and people that say an implementation may add other optional parameters seem to be wrong." is not true? I.e., are you saying that you now believe that an implementation can add additional parameters? Please clarify what "this answer" refers to. – Cheers and hth. - Alf Jan 18 '11 at 20:18
  • 1
    @Alf: He means the answer that we are talking on, as he clarified in a comment on another answer to this same question. The subsequent term "See" made it clear that he was changing the focus of his comment from "this answer", to a separate resource i.e. his own answer. – Lightness Races in Orbit Jan 18 '11 at 20:35
  • @Fred Nurk: thanks for the reference, that's indeed what I was looking for. It's indeed specific to default function arguments. BTW my GotW comment was in response to your "very similar to functions with additional defaulted parameters" quote. – MSalters Jan 20 '11 at 11:36
  • @MSalters: When I said that, I was referring to what you had already mentioned above: std::sin can't add additional defaulted parameters. – Fred Nurk Jan 20 '11 at 12:39