c++ - 为什么带有通用引用的重载(使用 enable_if)不起作用?

标签 c++ c++11 overloading template-meta-programming

使用 MS Visual C++ 2012 版本 11.0.51106.01 更新 1:

int x()
{
   return 3;
}

template <typename Fun>
typename std::enable_if<std::is_same<Fun, int()>::value, int>::type 
MySh(Fun& f)
{ 
   return f();
}

template <typename Fun>
typename std::enable_if<std::is_same<Fun, int()>::value, int>::type 
MySh1(Fun&& f)
{ 
   return f();
}

template <typename Fun>
int MySh2(Fun&& f)
{ 
   return f();
}

调用代码:

   int res = MySh(x); // compiles and returns 3
   res = MySh1(x); // doesn't compile with error: error C2893: Failed to specialize function template 'std::enable_if<std::is_same<Fun,int(void)>::value,int>::type MySh1(Fun &&)
   res = MySh2(x); // compiles and returns 3

我还没有尝试使用其他编译器(但),但目的是让它与 Visual C++ 2012 一起工作和/或向 Microsoft 报告编译器错误。

我想确保我没有忽略一些琐碎的事情并犯下愚蠢的错误。 当然,示例只是一个摘录,真正的预期用例更复杂并且与以下相关: Overloading on callables question

编辑: 我还对其他考虑因素感到困惑,例如:

   std::is_same<decltype(x), int()>::value; // true
   std::is_same<decltype(x), int(&)()>::value; //false

和:

template <typename Fun>
typename std::enable_if<std::is_same<Fun, int(&)()>::value, int>::type 
MySh1(Fun&& f)
{ 
   std::cout << typeid(f).name() << std::endl;   // prints int __cdecl(void)
   return f();
}

显然,我没有注意参数类型和实参类型之间的区别(Fun 与 f 和 x 相对)。

最佳答案

答案在错误中,将你的声明替换为

template <typename Fun>
typename std::enable_if<std::is_same<Fun, int(&)()>::value, int>::type 
    MySh1(Fun&& f)
{ 
    return f();
}

发生这种情况是因为标准对带有模板 <typename T> void foo(T&&); 的案例进行了特殊处理。

如果您将一些参数传递给 foo,则以下内容成立(以 int 为例):

  • 通过 lvalue int - Tint&
  • 通过 lvalue const int - Tconst int&
  • 通过 rvalue int - Tint
  • 通过 rvalue const int - Tconst int

article斯科特·迈耶斯 (Scott Meyers) 的研究人员可能会对此给予更多启发。

关于c++ - 为什么带有通用引用的重载(使用 enable_if)不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15048917/

相关文章:

c++ - 如何在 NS2 中查找节点 ID?

java - C++ 与 Java 中函数重载的歧义

c++ - 如何在 openCV 中读取 .tif 浮点灰度图像

c++ - 循环中的恒定条件 : compiler optimization

c++ - 使用 std::bind 时出现运行时错误

c++ - 传递对指针的引用

java - 如果在 Java 中如果在 C++ 中

c++ - 在 QtCreator 中启动应用程序时出现严重问题

c++ - 构造函数解析顺序的问题

java - 使用可变参数重载函数