15

As part of my toilet reading on the C++ Standard ANSI ISO IEC 14882 2003, I came across the following:

14.3.1.2: A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter.

While I get what a local type and a compound type are, what is an unnamed type? If a type is unnamed, how could you even attempt to use it in a template anyway, which prompted the standard to verbally exclude it?

Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
kirakun
  • 2,770
  • 1
  • 25
  • 41

2 Answers2

24

"Unnamed type" really means "unnamed enumeration or class type" [for more information, see the comments to this answer]. An enumeration or class type doesn't have to have a name. For example:

struct { int i; } x; // x is of a type with no name

You could try to use an unnamed type as a template argument through argument deduction:

template <typename T> void f(T) { }

struct { int i; } x;
f(x); // would call f<[unnamed-type]>() and is invalid in C++03

Note that this restriction has been lifted in C++0x, so this will be valid (you'll also be able to use local types as type template parameters). In C++0x, you could also use decltype to "name" an unnamed type:

template <typename T> void g() { }

struct { int i; } x;
f<decltype(x)>(); // valid in C++0x (decltype doesn't exist in C++03)
James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • @aaa: The restriction has been removed in C++0x. – James McNellis Feb 27 '11 at 06:02
  • Is `struct` the only way to have an unnamed type? Could you have an unnamed `class` too? – kirakun Feb 27 '11 at 06:03
  • 2
    @Kirakun: Yes -- structs and classes are basically the same. You can have the same thing with a union as well. – Jeremiah Willcock Feb 27 '11 at 06:04
  • 2
    @Kirakun: Yes, `struct` and `class` [are essentially the same](http://stackoverflow.com/questions/92859/what-are-the-differences-between-struct-and-class-in-c/999810#999810). Also: `enum { unnamed = 0 };`. – GManNickG Feb 27 '11 at 06:05
  • 1
    If a `class` is unnamed, how could you define its constructor? – kirakun Feb 27 '11 at 06:10
  • @Kirakun: You can't. A constructor is identified by the name of the class for which it is defined; if a class doesn't have a name, it can't have a constructor (or a destructor, for that matter). – James McNellis Feb 27 '11 at 06:23
  • 1
    -1 For not questioning authority. ;-) E.g. `int*` is an unnamed type according to your definition as I write this, yet can be used template argument. Re trusting authority (the standard), there is also a more subtle issue about named class types with unnamed type members. This more subtle issue is addressed by [DR #62](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#62), which (political?) does not mention the more obvious terminology issue, but whose proposed resolution addresses both issues. Anyway, in N3126 the text has been removed, replaced with a non-normative example. – Cheers and hth. - Alf Feb 27 '11 at 08:01
  • @Alf: Is it really fair to down-vote a canonically true answer? – GManNickG Feb 27 '11 at 08:03
  • 1
    @Gman: it's not a true answer. The answer says you can not use `int*` as template argument. You can. – Cheers and hth. - Alf Feb 27 '11 at 08:07
  • 1
    @Alf I see that, but perhaps a comment is good enough, and James can fix his answer to be more correct. (It does, after all, have good correct examples. +1 -1?) – GManNickG Feb 27 '11 at 09:06
  • @Alf we are teaching C++ which is defined by the spec. If the spec says you cannot use `int*` as a template argument, then you cannot do so. All the compilers that allow it are in error. BTW, `int` would also be an unnamed type. `int` is not a name (it's a keyword). – Johannes Schaub - litb Feb 27 '11 at 11:05
  • @Johannes: you know that that's gibberish. :-) and you know that i know that. but people who read it here will probably not know that it's gibberish, and you know that also. don't post such comments that communicate on two levels, please. you just mislead people: it's perfectly fine to use `int*` or `int` as template arguments. – Cheers and hth. - Alf Feb 27 '11 at 11:07
  • @Alf: You're right. I didn't even consult the spec to answer this question, I gave a conventional, practical answer. I didn't mean "name" in the standardese sense of the word, I meant it in the conventional sense of "can I write some sequence of characters that identifies the type." Would you prefer if the first sentence read "a type which cannot be named" or perhaps "a type for which no sequence of characters can be written to identify the type"? – James McNellis Feb 27 '11 at 15:41
  • 1
    @James I think the most straight forward is "an unnamed class or enumeration". – Johannes Schaub - litb Feb 27 '11 at 16:34
  • @James: agree with @Johannes, "an unnamed class or enumeration", and that's also the wording uses in proposed resolution of DR #62. And what's clearly *intended*. I'd add explanation that current wording is most probably a defect (AFAIK the standard does not define "unnamed type", and I searched the standard). Cheers, – Cheers and hth. - Alf Feb 27 '11 at 16:37
  • 1
    Say "that's clearly *intended*", then down-vote the answer that uses that as a premise saying "but it's not *so*". Needless pedantry, much? I don't understand this small crowd that knee-jerk down-votes an answer for even having a single possible incorrect nuanced bit of information, even though the rest of the answer is perfectly fine. Is this some game to try to find a reason to down-vote someone and you think you're winning? Relax. Help each other out. Don't be needlessly pedant; if that's your only skill then communicating with other humans may not be your thing. – GManNickG Feb 27 '11 at 21:42
  • @GMan personally I'm glad @Alf brought this up and had the balls to say "hey I just downvoted you". I think it's an interesting bug in the spec. Maybe it's too pedantic. But I can't complain, I give such downvotes too (not to this one though. I considered it "correct" already, since it does not contradict the spec. I only pedantry-downvote when someone contradicts the spec). – Johannes Schaub - litb Feb 27 '11 at 22:54
  • @Johannes: I'm glad it was brought up too, I'm just complaining about the method in which it was done. Maybe pedantry was a bad word since it's vague. – GManNickG Feb 27 '11 at 23:04
  • @GMan: I downvote incorrect answers. To me, "incorrect" is something of a judgment, but the final criterion is that it makes someone do something wrong, or prevents someone from doing something right. Which was the case here. Hence, downvote. I resent the social view that you propose here. It is totally misguided: you don't help people with technical stuff by ignoring their mistakes for social reasons. That's the opposite of helping. Just be true. – Cheers and hth. - Alf Feb 28 '11 at 08:38
  • @Alf: False dilemma, I never said "either ignore it completely or downvote". – GManNickG Feb 28 '11 at 09:03
2

Think about the following code:

template <typename T>
void foo(const T&) {}

struct {
  int x;
} y;
foo(y);

That includes an unnamed type. Note that the rule is different in C++0x.

Jeremiah Willcock
  • 30,161
  • 7
  • 76
  • 78