gpt4 book ai didi

c++ - 方法指针模板不编译

转载 作者:行者123 更新时间:2023-11-30 02:53:05 25 4
gpt4 key购买 nike

以下 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 '::', for the ERROR line.

失败行和未失败行之间的唯一区别是 bar_fails 通过“模板化类型定义”声明“方法指针类型”参数 void (TT::*)() ",而 bar_ok 直接声明它。

请注意,如果没有 const char* 的重载,模板化的 typedef 工作正常。在 const char* 重载可用的情况下,编译器错误地选择了 bar_fails 的 TT=[const char] 重载,但它正确地选择了 bar_ok 的 TT=Foo 重载。当 typedef 用于“简单”数据(如 TT* 或 float*)时,不会出现此问题。

最佳答案

原因是在bar_ok的情况下,SFINAE可以应用,因为错误的构造 const char::* 出现在模板参数替换的直接上下文中。在 bar_fail 情况下,它被删除了一步(隐藏在“模板类型定义”中),这意味着 SFINAE 不再适用,编译器必须处理 const char::*< 的语法废话,从而停止并报告错误。

换句话说,并不是编译器在bar_fail中选择了错误的重载。它必须在两种情况下检查两个过载,但在第一种情况下,SFINAE 允许忽略错误的情况,而在第二种情况下,它“为时已晚”。

关于c++ - 方法指针模板不编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18327388/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com