当使用自定义trait和bool类型的c++11枚举时,clang的编译错误

Compilation errors with clang when using a custom trait and a c++11 enum of type bool

本文关键字:枚举 c++11 clang 错误 编译 类型 自定义 trait bool      更新时间:2023-10-16

下面的代码在g++下可以很好地编译,但在clang(我测试过的所有版本)下无法编译:

#include <iostream>
namespace has_insertion_operator_impl
{
    typedef char no;
    typedef char yes[2];
    struct any_t
    {
        template <typename T>
        any_t(const T&);
    };
    yes& testStreamable(std::ostream&);
    no   testStreamable(no);
    no operator<<(const std::ostream&, const any_t&);
    template <typename T>
    struct has_insertion_operator
    {
        static std::ostream& s;
        static const T& t;
        static const bool value = sizeof(testStreamable(s << t)) == sizeof(yes);
    };
} // namespace has_insertion_operator_impl
template <typename T>
struct has_insertion_operator : has_insertion_operator_impl::has_insertion_operator<T>
{};
enum A : bool {
    Yup = true,
    Nop = false,
};
template <typename T>
bool getTraitVal(const T&) { return has_insertion_operator<T>::value; }
int main() { std::cout << getTraitVal(A::Yup) << std::endl; }

错误(只有clang !)如下:

prog.cc:24:59: error: use of overloaded operator '<<' is ambiguous (with operand types 'std::ostream' (aka 'basic_ostream<char>') and 'const A')
        static const bool value = sizeof(testStreamable(s << t)) == sizeof(yes);

我相信这是一个足够小的例子。以下是它的在线编译器链接:

  • 叮当声3.8
  • g + + 6.1

当我将枚举类型从bool改为int时,错误消失。

为什么会这样呢?这个问题最初是在使用doctest和Catch测试框架时发现的——下面是Catch的bug报告。会不会是一只叮当响的虫子?

我知道它不回答你的问题,但它似乎clang有一个问题与基础类型'bool'的枚举。

我把你的例子进一步简化为:

#include <iostream>
enum A : bool {
    Yup = true,
    Nop = false,
};
int main() { 
    A t = Yup;
    std::cout << t;
}

在这里你已经对正在发生的事情有了一个感觉:

prog.cc:10:15: error: use of overloaded operator '<<' is ambiguous (with operand types 'ostream' (aka 'basic_ostream<char>') and 'A')
    std::cout << t;
    ~~~~~~~~~ ^  ~
/usr/local/libcxx-3.8/include/c++/v1/ostream:195:20: note: candidate function
    basic_ostream& operator<<(bool __n);
                   ^
/usr/local/libcxx-3.8/include/c++/v1/ostream:198:20: note: candidate function
    basic_ostream& operator<<(int __n);
                   ^
...