Topic: Distinction b/w "enum" and "int" as template parameter?


Author: Allan_W@my-dejanews.com (Allan W)
Date: Mon, 9 Sep 2002 19:00:17 +0000 (UTC)
Raw View
SanPedro@nospam.org (San Pedro) wrote
> Unfortunately my draft of the standard does not have section 14.3.2,

Why not? Borrow a credit card and buy one online today. Skip lunch
for a few days to pay for it. Sheesh!

> does it state that integral promotions are *always* applied to
> integral/enumerated non-type template arguments?
>
> I did find the following in my copy (Nov 1996):
>
> 14.3/6
> Standard  conversions  (_conv_) are applied to an expression used as a
>   template-argument for a non-type template-parameter to bring it to the
>   type of its corresponding template-parameter.
> --> notice that type is mentioned here
>
> 14.5.5.2/2
> For  each  non-type template parameter, synthesize a unique value of
>     the appropriate type and substitute that for each occurrence of that
>     parameter in the function parameter list.
> --> again, appropriate type is mentioned for a non-type parameter
>
> Were these sections modified in the final draft?

14.3.2 Template non-type arguments [temp.arg.nontype]

1. A template-argument for a non-type, non-template template-parameter
   shall be one of:
   - an integral constant-expression of integral or enumeration type; or
   - the name of a non-type template-parameter, or
   - the name of an object or function with external linkage, including
     function templates and function template-ids but excluding
     non-static class members, expressed as & id-expression where the
     & is optional if the name refers to a function or array; or
   - a pointer to member expressed as described in 5.3.1.

2. [Note: A string literal (2.13.4) is not an acceptable template-argument
   because a string literal is an object with internal linkage. [Example:
      template<class T, char* p> class X {
              // ...
              X();
              X(const char* q) { /* ... */ }
      };
      X<int,"Studebaker"> x1; // error: string literal as template-argument

      char p[] = "Vivisectionist";
      X<int,p>x2;             // OK
  --end example] --end note]

3. [Note: Addresses of array elements and names or addresses of non-static
   class members are not acceptable template-arguments. [Example:
      template<int* p> class X { };

      int a[10];
      struct S { int m; static int s; } s;

      X<&a[2]> x3;     // error: address of array element
      X<&s.m>  x4;     // error: address of non-static member
      X<&s.s>  x5;     // error: &S::s must be used
      X<&S::s> x6;     // OK: address of static member
   -- end example] --end note]

4. [Note: Temporaries, unnamed lvalues, and named lvalues that do not
   have external linkage are not acceptable template-arguments when
   the corresponding template-parameter has reference type. [Example:
      template<const int& CRI> struct B { /* ... */ };

      B<1> b2;  // error: temporary would be required for template argument

      int c = 1;
      B<c> b1;  // OK
   -- end example] --end note]

5. The following conversions are performed on each expression used as a
   non-type template argument. If a non-type template-argument cannot be
   converted to the type of the corresponding template-parameter then
   the program is ill-formed.
   - For a non-type template-parameter of integral or enumeraion type,
     integral promotions (4.5) and integral conversions (4.7) are
     applied.
   - for a non-type template-parameter of type pointer to object,
     qualification conversions (4.4) and the array-to-pointer
     conversion (4.2) are applied. [Note: in particular, neither the
     null pointer conversion (4.10) nor the derived-to-base conversion
     (4.10) are applied. Although 0 is a valid template-argument
     for a non-type template parameter of pointer type.]
   - For a non-type template parameter of type reference to object, no
     conversions apply. The type referred to by the reference may be
     more cv-qualified than the (otherwise identical) type of the
     template-argument, which must be an lvalue.
   - For a non-type template-parameter of type pointer to function,
     only the function-to-pointer conversion (4.3) is applied. If the
     template-argument represents a set of overloaded functions (or a
     pointer to such), the matching function is selected from the set
     (13.4).
   - For a non-type template-parameter of type reference to function,
     no conversions apply. If the template-argument represents a set
     of overloaded functions, the matching function is selected from
     the set (13.4).
   - For a non-type template-parameter of type pointer to member
     function, no conversions apply. If the template-argument
     represents a set of overloaded functions, the matching function
     is selected from the set (13.4).
   - For a non-type template-parameter of type pointer to data
     member, qualification conversions (4.4) are applied.
   [Example:
      template<const int* pci> struct X { /* ... */ } ;
      int ai[10];
      X<ai> xi;    // array to pointer and qualification conversions

      struct Y { /* ... */ };
      template<const Y& b> struct Z { /* ... */ };
      Y y;
      Z<y> z;      // no conversion, but note extra cv-qualification

      template<int (&pa)[5]> struct W { /* ... */ };
      int b[5];
      W<b> w;

      void f(char);
      void f(int);

      template<void (*pf)(int)> struct A { /* ... */ };
      A<&f> a; // selects f(int)
   - End example]

> BTW, the Nov 96 draft can be found at
> http://www.comnets.rwth-aachen.de/doc/c++std/

And other places, as specified in the FAQ.
> [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]
But buy a copy of the standard!

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: vAbazarov@dAnai.com ("Victor Bazarov")
Date: Tue, 3 Sep 2002 16:47:42 +0000 (UTC)
Raw View
"San Pedro" <SanPedro@nospam.org> wrote...
> [...]
> In the following code, the compiler cannot distinguish between any of
these
> overloaded functions.
>
>
> template <int value>
> void AcceptsNonTypeIntegral();
>
> template <char value>
> void AcceptsNonTypeIntegral();
>
> enum DaysOfWeek = {sun, mon, tue, wed, thu, fri, sat};
>
> template <DaysOfWeek value>
> void AcceptsNonTypeIntegral();
>
>
> Thus int(2)==char(2)==DaysOfWeek(2)==tue when used as a non-type template
> argument.  I could not find anything in the standard that says the type of
an
> argument is ignored when used as a non-type argument, or that integral
> promotions are performed on all integral values used as non-type
arguments.

Try 14.3.2/5, the first bullet item.

> The only thing I did find is 14.1p3 which mentions enumeration types
> separately from integral types as potential non-type template parameters.
>
> Does anyone know whether this is correct behavior, or just one
interpretation
> of an unspecified facet of the language?

This is _standard_ behaviour.

Victor
--
Please remove capital A's from my address when replying by mail



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: SanPedro@nospam.org (San Pedro)
Date: Tue, 3 Sep 2002 18:21:25 +0000 (UTC)
Raw View
Rani Sharoni wrote:

> San Pedro <SanPedro@nospam.org> wrote
> >
> > In the following code, the compiler cannot distinguish between any of these
> > overloaded functions.
> >
> >
> > template <int value>
> > void AcceptsNonTypeIntegral();
> >
> > template <char value>
> > void AcceptsNonTypeIntegral();
> >
> > enum DaysOfWeek = {sun, mon, tue, wed, thu, fri, sat};
> >
> > template <DaysOfWeek value>
> > void AcceptsNonTypeIntegral();
> >
> >
> > Thus int(2)==char(2)==DaysOfWeek(2)==tue when used as a non-type template
> > argument.  I could not find anything in the standard that says the type of an
> > argument is ignored when used as a non-type argument, or that integral
> > promotions are performed on all integral values used as non-type arguments.
> > The only thing I did find is 14.1p3 which mentions enumeration types
> > separately from integral types as potential non-type template parameters.
> >
> > Does anyone know whether this is correct behavior, or just one interpretation
> > of an unspecified facet of the language?
> >
>
> This is interesting idea but I suspect that it's illegal in C++.
> According to 14.3.2/5: for a non-type template-parameter of integral
> or enumeration type, integral promotions (4.5) and integral
> conversions (4.7) are applied.
>
> There is no overload ranking for the candidate templates which lead to
> ambiguity in the above code (According to Comeau 4.3.0.1 and other
> compilers).
>
> You might use the following technique to simulate this special
> "overloading":
>
> template<typename> struct Type2Type {};
>
> template<typename T>
> Type2Type<T> DetectType(const T &);
>
> template <int value>
> void AcceptsNonTypeIntegral(Type2Type<int>);
>
> template <char value>
> void AcceptsNonTypeIntegral(Type2Type<char>);
>
> enum DaysOfWeek {sun, mon, tue, wed, thu, fri, sat};
>
> template <DaysOfWeek value>
> void AcceptsNonTypeIntegral(Type2Type<DaysOfWeek>);
>
> #define MAC_AcceptsNonTypeIntegral(value) \
>     AcceptsNonTypeIntegral<value>(DetectType(value))
>
> void Temp()
> {
>     MAC_AcceptsNonTypeIntegral(10);
>     MAC_AcceptsNonTypeIntegral('A');
>     MAC_AcceptsNonTypeIntegral(sun);
> }
>
> The above code compiled fine with Comeau and other compilers I tried.
>
> Enjoy,
> Rani

This is a suitable workaround for my dilemma, thanks!

Unfortunately my draft of the standard does not have section 14.3.2, does it state
that integral promotions are *always* applied to integral/enumerated non-type
template arguments?

I did find the following in my copy (Nov 1996):

14.3/6
Standard  conversions  (_conv_) are applied to an expression used as a
  template-argument for a non-type template-parameter to bring it to the
  type of its corresponding template-parameter.
--> notice that type is mentioned here

14.5.5.2/2
For  each  non-type template parameter, synthesize a unique value of
    the appropriate type and substitute that for each occurrence of that
    parameter in the function parameter list.
--> again, appropriate type is mentioned for a non-type parameter

Were these sections modified in the final draft?

BTW, the Nov 96 draft can be found at http://www.comnets.rwth-aachen.de/doc/c++std/

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Allan_W@my-dejanews.com (Allan W)
Date: 30 Aug 2002 20:00:01 GMT
Raw View
San Pedro <SanPedro@nospam.org> wrote
> In the following code, the compiler cannot distinguish between any of these
> overloaded functions.
>
> template <int value>
> void AcceptsNonTypeIntegral();
>
> template <char value>
> void AcceptsNonTypeIntegral();
>
> enum DaysOfWeek = {sun, mon, tue, wed, thu, fri, sat};
>
> template <DaysOfWeek value>
> void AcceptsNonTypeIntegral();
>
>
> Thus int(2)==char(2)==DaysOfWeek(2)==tue when used as a non-type template
> argument.  I could not find anything in the standard that says the type of an
> argument is ignored when used as a non-type argument, or that integral
> promotions are performed on all integral values used as non-type arguments.
> The only thing I did find is 14.1p3 which mentions enumeration types
> separately from integral types as potential non-type template parameters.

Interesting coding technique, San Pedro. Here you are doing something
very similar to overloading, except that you're doing it on template
parameters. Let's call this "Template Parameter Overloading."

> Does anyone know whether this is correct behavior, or just one
> interpretation of an unspecified facet of the language?

I don't know anyone else that's ever tried this. Which isn't to say
that it isn't valid. I think that at least under the principal of
least surprise, it ought to work. I don't have anything to back this
up, though.

You're certainly asking in the right place. Hopefully, someone wiser
than me will be interested...

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Paul Mensonides" <pmenso57@attbi.com>
Date: Fri, 30 Aug 2002 15:52:54 CST
Raw View
"Allan W" <Allan_W@my-dejanews.com> wrote in message
news:23b84d65.0208301139.786f604f@posting.google.com...

> Interesting coding technique, San Pedro. Here you are doing something
> very similar to overloading, except that you're doing it on template
> parameters. Let's call this "Template Parameter Overloading."
>
> > Does anyone know whether this is correct behavior, or just one
> > interpretation of an unspecified facet of the language?
>
> I don't know anyone else that's ever tried this. Which isn't to say
> that it isn't valid. I think that at least under the principal of
> least surprise, it ought to work. I don't have anything to back this
> up, though.

I looked into this a while back.  I'm not sure about enumerations, but I'm
pretty sure that you can't do this with built-in integral types.  It doesn't
overload that way.

Paul Mensonides

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: rani_sharoni@hotmail.com (Rani Sharoni)
Date: 31 Aug 2002 20:05:04 GMT
Raw View
San Pedro <SanPedro@nospam.org> wrote
>
> In the following code, the compiler cannot distinguish between any of these
> overloaded functions.
>
>
> template <int value>
> void AcceptsNonTypeIntegral();
>
> template <char value>
> void AcceptsNonTypeIntegral();
>
> enum DaysOfWeek = {sun, mon, tue, wed, thu, fri, sat};
>
> template <DaysOfWeek value>
> void AcceptsNonTypeIntegral();
>
>
> Thus int(2)==char(2)==DaysOfWeek(2)==tue when used as a non-type template
> argument.  I could not find anything in the standard that says the type of an
> argument is ignored when used as a non-type argument, or that integral
> promotions are performed on all integral values used as non-type arguments.
> The only thing I did find is 14.1p3 which mentions enumeration types
> separately from integral types as potential non-type template parameters.
>
> Does anyone know whether this is correct behavior, or just one interpretation
> of an unspecified facet of the language?
>

This is interesting idea but I suspect that it's illegal in C++.
According to 14.3.2/5: for a non-type template-parameter of integral
or enumeration type, integral promotions (4.5) and integral
conversions (4.7) are applied.

There is no overload ranking for the candidate templates which lead to
ambiguity in the above code (According to Comeau 4.3.0.1 and other
compilers).

You might use the following technique to simulate this special
"overloading":

template<typename> struct Type2Type {};

template<typename T>
Type2Type<T> DetectType(const T &);

template <int value>
void AcceptsNonTypeIntegral(Type2Type<int>);

template <char value>
void AcceptsNonTypeIntegral(Type2Type<char>);

enum DaysOfWeek {sun, mon, tue, wed, thu, fri, sat};

template <DaysOfWeek value>
void AcceptsNonTypeIntegral(Type2Type<DaysOfWeek>);

#define MAC_AcceptsNonTypeIntegral(value) \
    AcceptsNonTypeIntegral<value>(DetectType(value))

void Temp()
{
    MAC_AcceptsNonTypeIntegral(10);
    MAC_AcceptsNonTypeIntegral('A');
    MAC_AcceptsNonTypeIntegral(sun);
}

The above code compiled fine with Comeau and other compilers I tried.

Enjoy,
Rani

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: San Pedro <SanPedro@nospam.org>
Date: Wed, 28 Aug 2002 15:48:25 CST
Raw View
Apparently my compiler does not distinguish between "int" and "enum"
when used as a non-type parameter for a template function.  However, it
does distinguish between the two when determining which overloaded
function to call, and for class template specialization/instantiation.

Is this standard conforming behavior or a quirk of my compiler?

I have included some sections from the (1996 draft) standard, which
hopefully have not been changed in the final draft.  I suppose that it
is clear that 'enum's are separate types from 'int's, and that template
functions taking type-parameters of either int or enum should be
differentiated.  What is not clear, is whether int values are equivalent
to enum values for the purpose of differentiating non-type templates.
I.e., in the example below does color(yellow)==int(1)?

7.2  Enumeration declarations                               [dcl.enum]

1 An  enumeration is a distinct type (_basic.fundamental_) with named
constants.


14.1  Template parameters                                 [temp.param]

3 A non-type template-parameter shall have one of the following
(optionally cv-qualified) types:

  --integral type, accepting an integral constant expression as an
argument,

  --enumeration  type,  accepting  an integral constant expression as an
argument,


14.5.5.1  Function template overloading               [temp.over.link]

3 The signature of a function template specialization consists of the
signature of the function template and of the actual template arguments
(whether explicitly specified or deduced).

4 The signature of a function template consists of its function
signature, its return type and its template parameter list.  The names
of the template parameters are significant only for  establishing the
relationship between the template parameters and the rest of the
signature.


14.4  Type equivalence                                     [temp.type]

1 Two template-ids refer to the same class or function if their template
names are identical, they refer to the same template, their type
template-arguments  are  the same type and, their non-type
template-arguments have identical values.
[Example:
          template<class E, int size> class buffer { /* ... */ };
          buffer<char,2*512> x;
          buffer<char,1024> y;


7.2  Enumeration declarations                               [dcl.enum]

8 The value of an enumerator or an object of an enumeration type is
converted to an integer by integral promotion (_conv.prom_).  [Example:
      enum color { red, yellow, green=20, blue };
      color col = red;
      color* cp = &col;
      if (*cp == blue) // ...
makes color a type describing various colors, and then declares col as
an object of that type, and cp as a pointer to an object of that type.
The possible values of an object of type color are red, yellow, green,
blue; these values can be converted to the integral values 0,  1,  20,
and  21.  Since enumerations are distinct types, objects of type color
can be assigned only values of type color.





//////////////////////////////////////////////
#include <iostream>
#include <typeinfo>


using ::std::cin;
using ::std::cout;
using ::std::endl;

//////////////////////////////////////////////

enum DotW {sun, mon, tue, wed, thu, fri, sat};

const char * dayNames[7] =
{
 "Sunday",
 "Monday",
 "Tuesday",
 "Wednesday",
 "Thursday",
 "Friday",
 "Saturday"
};

//////////////////////////////////////////////

template <int value>
void
EnumOrInt()
{
 cout << value << endl;
}

/*
Does not compile...
error: more than one instance of overloaded
function "EnumOrInt" matches the argument list:
  function template "EnumOrInt<value>()"
  function template "EnumOrInt<value>()"

template <DotW value>
void
EnumOrInt()
{
 cout << dayNames[value] << endl;
}
*/

//////////////////////////////////////////////

void
EnumOrInt(int value)
{
 cout << value << endl;
}


void
EnumOrInt(DotW value)
{
 cout << dayNames[value] << endl;
}

//////////////////////////////////////////////

template <typename IntegralType>
class WhichType
{
 public:
  static void PrintType()
  {
   cout << typeid(IntegralType).name() << endl;
  }
};


template<> class WhichType<int>;

//////////////////////////////////////////////

int main()
{
 EnumOrInt<tue>();

 EnumOrInt(tue);

 WhichType<DotW>::PrintType();

 cout << "Press any key to continue" << endl;
 cin.get();

 return 0;
}

//////////////////////////////////////////////
Output:
2
Tuesday
DotW
Press any key to continue

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: San Pedro <SanPedro@nospam.org>
Date: 29 Aug 2002 17:05:17 GMT
Raw View

San Pedro wrote:

> Apparently my compiler does not distinguish between "int" and "enum"
> when used as a non-type parameter for a template function.  However, it
> does distinguish between the two when determining which overloaded
> function to call, and for class template specialization/instantiation.
>
> Is this standard conforming behavior or a quirk of my compiler?
>
> I have included some sections from the (1996 draft) standard, which
> hopefully have not been changed in the final draft.  I suppose that it
> is clear that 'enum's are separate types from 'int's, and that template
> functions taking type-parameters of either int or enum should be
> differentiated.  What is not clear, is whether int values are equivalent
> to enum values for the purpose of differentiating non-type templates.
> I.e., in the example below does color(yellow)==int(1)?
>
> 7.2  Enumeration declarations                               [dcl.enum]
>
> 1 An  enumeration is a distinct type (_basic.fundamental_) with named
> constants.
>
> 14.1  Template parameters                                 [temp.param]
>
> 3 A non-type template-parameter shall have one of the following
> (optionally cv-qualified) types:
>
>   --integral type, accepting an integral constant expression as an
> argument,
>
>   --enumeration  type,  accepting  an integral constant expression as an
> argument,
>
> 14.5.5.1  Function template overloading               [temp.over.link]
>
> 3 The signature of a function template specialization consists of the
> signature of the function template and of the actual template arguments
> (whether explicitly specified or deduced).
>
> 4 The signature of a function template consists of its function
> signature, its return type and its template parameter list.  The names
> of the template parameters are significant only for  establishing the
> relationship between the template parameters and the rest of the
> signature.
>
> 14.4  Type equivalence                                     [temp.type]
>
> 1 Two template-ids refer to the same class or function if their template
> names are identical, they refer to the same template, their type
> template-arguments  are  the same type and, their non-type
> template-arguments have identical values.
> [Example:
>           template<class E, int size> class buffer { /* ... */ };
>           buffer<char,2*512> x;
>           buffer<char,1024> y;
>
> 7.2  Enumeration declarations                               [dcl.enum]
>
> 8 The value of an enumerator or an object of an enumeration type is
> converted to an integer by integral promotion (_conv.prom_).  [Example:
>       enum color { red, yellow, green=20, blue };
>       color col = red;
>       color* cp = &col;
>       if (*cp == blue) // ...
> makes color a type describing various colors, and then declares col as
> an object of that type, and cp as a pointer to an object of that type.
> The possible values of an object of type color are red, yellow, green,
> blue; these values can be converted to the integral values 0,  1,  20,
> and  21.  Since enumerations are distinct types, objects of type color
> can be assigned only values of type color.
>
> //////////////////////////////////////////////
> #include <iostream>
> #include <typeinfo>
>
> using ::std::cin;
> using ::std::cout;
> using ::std::endl;
>
> //////////////////////////////////////////////
>
> enum DotW {sun, mon, tue, wed, thu, fri, sat};
>
> const char * dayNames[7] =
> {
>  "Sunday",
>  "Monday",
>  "Tuesday",
>  "Wednesday",
>  "Thursday",
>  "Friday",
>  "Saturday"
> };
>
> //////////////////////////////////////////////
>
> template <int value>
> void
> EnumOrInt()
> {
>  cout << value << endl;
> }
>
> /*
> Does not compile...
> error: more than one instance of overloaded
> function "EnumOrInt" matches the argument list:
>   function template "EnumOrInt<value>()"
>   function template "EnumOrInt<value>()"
>
> template <DotW value>
> void
> EnumOrInt()
> {
>  cout << dayNames[value] << endl;
> }
> */
>
> //////////////////////////////////////////////
>
> void
> EnumOrInt(int value)
> {
>  cout << value << endl;
> }
>
> void
> EnumOrInt(DotW value)
> {
>  cout << dayNames[value] << endl;
> }
>
> //////////////////////////////////////////////
>
> template <typename IntegralType>
> class WhichType
> {
>  public:
>   static void PrintType()
>   {
>    cout << typeid(IntegralType).name() << endl;
>   }
> };
>
> template<> class WhichType<int>;
>
> //////////////////////////////////////////////
>
> int main()
> {
>  EnumOrInt<tue>();
>
>  EnumOrInt(tue);
>
>  WhichType<DotW>::PrintType();
>
>  cout << "Press any key to continue" << endl;
>  cin.get();
>
>  return 0;
> }
>
> //////////////////////////////////////////////
> Output:
> 2
> Tuesday
> DotW
> Press any key to continue
>
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]

I initially misunderstood the error message, believing that the error was
occuring during the parsing of the declaration/definition, when in fact it
was occuring at the function call.  The compiler was unable to resolve which
overloaded function to call.

In the following code, the compiler cannot distinguish between any of these
overloaded functions.


template <int value>
void AcceptsNonTypeIntegral();

template <char value>
void AcceptsNonTypeIntegral();

enum DaysOfWeek = {sun, mon, tue, wed, thu, fri, sat};

template <DaysOfWeek value>
void AcceptsNonTypeIntegral();


Thus int(2)==char(2)==DaysOfWeek(2)==tue when used as a non-type template
argument.  I could not find anything in the standard that says the type of an
argument is ignored when used as a non-type argument, or that integral
promotions are performed on all integral values used as non-type arguments.
The only thing I did find is 14.1p3 which mentions enumeration types
separately from integral types as potential non-type template parameters.

Does anyone know whether this is correct behavior, or just one interpretation
of an unspecified facet of the language?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]