如何在 using 语句中使用 std::is_same_v?

How do I use std::is_same_v in a using statement?

考虑以下代码:

template<typename T>
using IsInt = std::is_same<T, int>::value;

template<class SrcType, class DstType>
constexpr DstType As(SrcType val) {
  if constexpr (IsInt<SrcType>) return val;
}

此代码在 C++17 下编译良好,但如果我使用 std::is_same_v<...> 而不是 std::is_same<...>::value,则 GCC 会抱怨:

error: 'std::is_same_v<_Tp, _Up>' in namespace 'std' does not name a template type

我猜错误是由于 std::is_same_v 被声明为 constexpr。我该如何修复它(同时保持类型别名)?

实际上,示例代码无法编译。

#include <type_traits>

template<typename T>
using IsInt = std::is_same<T, int>::value;

此处的using 声明用于类型别名。在 C++17 中,它必须是

template<typename T>
using IsInt = typename std::is_same<T, int>::value;

但是,这是不正确的,因为 std::is_same<T, int>::value 不是 类型,它是一个值,而我们希望 IsInt 是一个值嗯。

(在 C++20 中,因为这种 using 表达式的右侧只有类型名在语法上是正确的,所以这里不再需要使用 typename 关键字,但它仍在创建类型别名,这不是预期的。)

所以我们真正想要的是 C++17 为其 _v 便利成员使用的同一种帮助程序:

template<typename T>
inline constexpr bool IsInt = std::is_same<T, int>::value;

以下也适用:

template<typename T>
inline constexpr bool IsInt = std::is_same_v<T, int>;

inline 假设它存在于 header 中,我们想在多个翻译单元中使用相同的定义,constexpr 因为它在编译时已知,这让我们可以使用它用于 if constexpr 或其他目的。