使用MSVC编译器中的枚举类“对重载函数进行模糊调用”

时间:2017-10-26 14:56:03

标签: c++ c++11 visual-c++

我试图用值进行模板特化,一个化身是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枚举类的一个原因是避免隐式转换,但不确定。这是编译器错误,还是标准中的一些缺陷?

1 个答案:

答案 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;
}

works on this online MSVC compiler