当前位置: 动力学知识库 > 问答 > 编程问答 >

c++ - Why can't I downcast pointer to members in template arguments?

问题描述:

If I make a pointer-to-base-member, I can convert it to a pointer-to-derived-member usually, but not when used within a template like Buzz below, where the first template argument influences the second one. Am I fighting compiler bugs or does the standard really mandate this not work?

struct Foo

{

int x;

};

struct Bar : public Foo

{

};

template<class T, int T::* z>

struct Buzz

{

};

static int Bar::* const workaround = &Foo::x;

int main()

{

// This works. Downcasting of pointer to members in general is fine.

int Bar::* y = &Foo::x;

// But this doesn't, at least in G++ 4.2 or Sun C++ 5.9. Why not?

// Error: could not convert template argument '&Foo::x' to 'int Bar::*'

Buzz<Bar, &Foo::x> test;

// Sun C++ 5.9 accepts this but G++ doesn't because '&' can't appear in

// a constant expression

Buzz<Bar, static_cast<int Bar::*>(&Foo::x)> test;

// Sun C++ 5.9 accepts this as well, but G++ complains "workaround cannot

// appear in a constant expression"

Buzz<Bar, workaround> test;

return 0;

}

网友答案:

It simply isn't allowed. According to §14.3.2/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 enumeration 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. — 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. The template-parameter is bound directly to 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 member functions, the matching member 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.

I've emphasized the conversion regarding pointer to data members. Note that your conversion (§4.11/2) is not listed. In C++0x, it remains the same in this regard.

分享给朋友:
您可能感兴趣的文章:
随机阅读: