C++ &引用;对重载函数的调用不明确;在MSVC编译器中使用枚举类

C++ &引用;对重载函数的调用不明确;在MSVC编译器中使用枚举类,c++,c++11,visual-c++,C++,C++11,Visual C++,我试图用值进行模板专门化,一个是bool,另一个是enum类。我与编译器斗争了一天,但未能克服“对重载函数的模糊调用”错误。 这段代码很难看,而且相当长,但下面是一个简单的测试用例: #include <iostream> enum class Foo { Bar }; enum class Waldo { Fred }; template<Foo ARG, typename... _Types> inline bool DOIT( _Types&&.

我试图用值进行模板专门化,一个是bool,另一个是enum类。我与编译器斗争了一天,但未能克服“对重载函数的模糊调用”错误。 这段代码很难看,而且相当长,但下面是一个简单的测试用例:

#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;
}
#包括
枚举类Foo{Bar};
枚举类Waldo{Fred};
模板
内联布尔DOIT(_类型&&…_参数)
{
返回true;
}
模板
内联布尔DOIT(_类型&&…_参数)
{
返回false;
}
int main()
{

std::cout从技术上讲,您发布的代码是一个格式错误的程序,不需要进行诊断,因为您使用了一个标识符,该标识符以
开头,后跟一个大写字母。该标准为编译器的实现者保留了此类标识符

但那不是你的问题


我曾经看到过一个案例,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;
}
模板
内联布尔DOIT(std::integral_常量,Ts&&…args)
{
返回true;
}
模板
内联布尔DOIT(std::integral_常量,Ts&&…args)
{
返回false;
}
int main()
{

std::cout考虑到您使用的是作用域枚举,这肯定是MSVC的一个小问题。Visual Studio中内置的铿锵编译器说“错误:定义与另一个定义具有相同的损坏名称”。让我想起一个旧的VC++错误,他们将名称与函数参数类型,而不是模板类型相混淆。也许这个问题仍然存在?