以下 C++ 代码无法在 MS Visual Studio 2010 中编译:
class Foo
{
public:
/// Provides the signature of the methods that can be given to addValueSetListener
template <typename TT>
struct ChangeHandler
{
typedef void ( TT::* OnSetValueMethod )();
};
template <typename TT>
void bar_ok(TT*, void ( TT::* )(), bool = false) {}
template <typename TT>
void bar_ok(const char*, TT*, void ( TT::* )()) {}
template <typename TT>
void bar_fails(TT*, typename ChangeHandler<TT>::OnSetValueMethod, bool = false) {}
template <typename TT>
void bar_fails(const char*, TT*, typename ChangeHandler<TT>::OnSetValueMethod) {}
void testBar() {}
};
int main()
{
Foo foo;
foo.bar_ok ("allo",& foo, & Foo::testBar); // compiles
foo.bar_fails("allo",& foo, & Foo::testBar); // compile ERROR
}
'TT': must be a class or namespace when followed by '::'
对于 ERROR 行,编译器错误是,。
失败的行和不失败的行之间的唯一区别是 bar_failsvoid (TT::*)()
通过“模板化 typedef”声明“方法指针类型”参数,而 bar_ok 直接声明它。
请注意,如果没有 for 的重载const char*
,模板化的 typedef 可以正常工作。由于 const char* 重载可用,编译器错误地选择了TT=[const char]
bar_fails 的重载,但它正确地选择了 bar_ok 的 TT=Foo 重载。当 typedef 用于 TT* 或 float* 等“简单”数据时,不会出现此问题。