我试图用值进行模板特化,一个化身是bool,而另一个是枚举类。我与编译器争夺了一天,但没有设法克服“对重载函数的模糊调用”错误。 这段代码很丑陋而且很长,但这是一个简单的测试用例:
#include <iostream>
enum class Foo { Bar };
enum class Waldo { Fred };
template<Foo ARG, typename... _Types>
inline bool DOIT( _Types&&... _Args )
{
return true;
}
template<Waldo ARG, typename... _Types>
inline bool DOIT( _Types&&... _Args )
{
return false;
}
int main()
{
std::cout << DOIT<Foo::Bar>() << std::endl;
std::cout << DOIT<Waldo::Fred>() << std::endl;
return 0;
}
clang 3.8和gcc 4.8.3都可以毫不费力地编译,标准设置为c ++ 11,但是MSVC不断向我发出C2668错误消息。
AFAIK枚举类的一个原因是避免隐式转换,但不确定。这是编译器错误,还是标准中的一些缺陷?
答案 0 :(得分:5)
从技术上讲,您发布的代码是一个格式错误的程序,无需诊断,因为您使用的标识符以_
开头,后跟大写字母。这些标识符由编译器实现者的标准保留。
但这不是你的问题。
我见过一个案例,其中MSVC是正确的,而两者 gcc和clang在遵循标准时出错了。
最重要的是,歧义在这里毫无意义。
您的编译器已被破坏。
应该有效的方法是:
template<Foo ARG, typename... Ts>
inline bool DOIT( std::integral_constant<Foo, ARG>, Ts&&... args )
{
return true;
}
template<Waldo ARG, typename... Ts>
inline bool DOIT( std::integral_constant<Waldo, ARG>, Ts&&... args )
{
return false;
}
int main()
{
std::cout << DOIT(std::integral_constant<Foo, Foo::Bar>{}) << std::endl;
std::cout << DOIT(std::integral_constant<Waldo, Waldo::Fred>{}) << std::endl;
return 0;
}