std::is_same 和 std::get 在一起

std::is_same and std::get together

我试图检查特定类型是否在类型列表(元组)中。而且 运行 遇到了一些麻烦 :

#include  <tuple>
#include  <iostream>

template < typename T >
struct Type {

  using type = T;
};

int main() {

  constexpr auto Foo = std::make_tuple(Type<int>{},Type<int>{});
  if (std::is_same<int, std::get<0>(Foo)::type>::value)
    std::cout << "GG!" << std::endl;
  return 0;
}

test.cpp: In function ‘int main()’:
test.cpp:13:47: error: type/value mismatch at argument 2 in template parameter list for ‘template<class, class> struct std::is_same’
   if (std::is_same<int, std::get<0>(Foo)::type>::value)
                                               ^
test.cpp:13:47: note:   expected a type, got ‘std::get<0ul, {Type<int>, Type<int>}>(Foo)’

似乎 std::get 没有给我显示我想要的类型。谁能解释一下为什么?

std::get<0>(Foo)::type 在此上下文中没有任何意义,因为 std::get<0>(Foo) 是一个值,而不是类型。

改为试试这个:我们将使用 decltype() 来获取该表达式的类型(而不实际评估其值)。这将导致 Type<int>& 类型。我们将使用 std::decay 删除引用(因为 Type<int>&::type 也没有意义),然后我们可以访问它的 type typedef.

它有点笨拙,但它确实有效:

if (
  std::is_same<
    int,

    // The decltype will be (Type<int>&). Decay to remove the
    // reference, cv-qualifiers, etc.
    std::decay< 
      decltype(std::get<0>(Foo))
    >::type::type
    // ^ Two ::types, one to extract the type from std::decay, one
    // for your Type<T> struct.
  >::value
) {
    std::cout << "GG!" << std::endl;
}

(Demo)

当然可能有更好的方法来完成此检查,但这是一种方法。