【问题标题】:"Ambiguous call to overloaded function" with enum classes in MSVC compilers在 MSVC 编译器中使用枚举类“对重载函数的模糊调用”
【发布时间】:2017-10-26 14:56:03
【问题描述】:

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

【问题讨论】:

  • 考虑到您使用范围枚举,肯定是 MSVC 打嗝。
  • Visual Studio 中内置的 clang 编译器显示 “错误:定义与另一个定义具有相同的错误名称”。让我想起了一个旧的 VC++ 错误,他们用函数参数类型而不是模板类型来破坏名称。也许这个问题仍然存在?

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


【解决方案1】:

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

但这不是你的问题。


我曾经见过一个案例,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.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多