Question

The following code is a simplified minimal version of a feature I am trying to implement for a client requirement.

It fails to compile on IBM's XLC compiler (version 9 and 11, both) with the error A non-type template parameter cannot have type "int X::*".. However, I have tried the same code with g++ 4.7.2, clang++ 3.2 and Intel-13.0, and they compile it successfully.

I am curious to know if XLC is the only sane voice here, or are the other compilers correct?

struct X {
    X() : y(123) {}
    int y;
};

struct XFoo {
   typedef int X::* Type;
};

template <typename Name, typename Name::Type value>
struct Bar {
    typename Name::Type getValue(Name) {
        return value;
    }
};

template class Bar<XFoo, &X::y>;    // xlc error here, works fine on others

int main() {}

I read through the C++ 2003 standard chapter on templates several times, and could not conclusively find something which prohibits using <type> <class>::* as a non-template type. I have already searched through SO and search engines for an explanation, but have not come across any authoritative source which helps me decide.

I understand that this may not be a good coding practice, but this is required for the client code since their requirement is somewhat unique. I have also tried out various other alternatives but it does not work for them.

Was it helpful?

Solution

§ 14.1/4 of the C++03 Standard allows having pointers to member as a template parameter:

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

  • integral or enumeration type,
  • pointer to object or pointer to function,
  • reference to object or reference to function,
  • pointer to member.

Correspondingly, per § 14.3.2/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 address 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 if the corresponding template-parameter is a reference; or
  • a pointer to member expressed as described in 5.3.1.

Thus, non-type template parameters can be pointers to member. There are some limitations which apply to template specialization, but they don't seem to apply in this case.

OTHER TIPS

Pointer-to-member template parameters are explicitly allowed, XLC should be served a bug report.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top