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

时间:2016-11-09 09:50:25

标签: c++ c++11 compiler-errors clang

以下代码使用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);

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

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

那为什么会这样呢?这最初是在使用doctestCatch测试框架时发现的 - 这里是Catch的bug report。它可能是一个铿锵的错误吗?

1 个答案:

答案 0 :(得分:2)

我知道它没有回答你的问题,但似乎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);
                   ^
...