【问题标题】:Why does SFINAE not give the correct result for incrementing bool?为什么 SFINAE 没有给出递增布尔值的正确结果?
【发布时间】:2018-06-24 16:28:59
【问题描述】:

我写了一个这样的is_incrementable trait:

#include <type_traits>

template <typename T, typename = void>
struct is_incrementable : std::false_type {};

template <typename T>
struct is_incrementable<T, std::void_t<decltype(++std::declval<T&>())>>
    : std::true_type {};

template <typename T>
constexpr bool is_incrementable_v = is_incrementable<T>::value;

当我将它应用到bool-std=c++17 时,它返回true

// This compiles
static_assert(is_incrementable_v<bool>, "");

但在 c++17 下不允许递增 bool。事实上,如果我尝试这样做,我会得到一个错误:

bool b = false;
++b;

结果:

error: ISO C++17 does not allow incrementing expression of type bool [-Wincrement-bool]

为什么 SFINAE 报告 bool 是可递增的,而编译器显然不允许这样做?

编译器资源管理器:https://godbolt.org/g/DDFYBf

【问题讨论】:

  • 它确实在 GCC 中给出了预期的静态断言失败,这至少暗示它可能只是 clang 中的一个错误。
  • @max66 因为operator ++ 需要一个左值
  • 是的,开始认为这是一个编译器错误。 GCC 似乎确实做了正确的事情。
  • 是的,这似乎是一个错误。如果你从 declval 中删除引用,它对我有用。

标签: c++ sfinae typetraits


【解决方案1】:

看起来 Clang 错误地允许在未评估的上下文中增加 bool 值。

我们可以使用 C++20 概念简化您的示例:

template<class T>
concept is_incrementable = requires(T t) {
    { ++t };
};

int main() {
    static_assert( is_incrementable<int> );
    static_assert( !is_incrementable<bool> ); // Clang error here
}

这个程序在 GCC 和 MSVC 中被接受,但是 Clang 在这里显示了同样的错误行为,演示:https://gcc.godbolt.org/z/YEnKfG8T5

我认为是 Clang 的 bug,所以提交了一个 bug 报告:https://bugs.llvm.org/show_bug.cgi?id=52280

【讨论】:

    猜你喜欢
    • 2016-03-31
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    相关资源
    最近更新 更多