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

use*_*650 3 c++ visual-c++ c++11

我试图用值进行模板特化,一个化身是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;
}
Run Code Online (Sandbox Code Playgroud)

clang 3.8和gcc 4.8.3都可以顺利编译,标准设置为c ++ 11,但MSVC不断向我发出C2668错误消息.

AFAIK枚举类的一个原因是避免隐式转换,但不确定.这是编译器错误,还是标准中的一些缺陷?

Yak*_*ont 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;
}
Run Code Online (Sandbox Code Playgroud)

适用于本次网上MSVC编译器.