使用表单中声明的std::declval
不是更好:
template< class T > T declval(); // (1)
然后是当前的一个:
template< class T > T && declval(); // (2)
for std::common_type
(可能只为当前目的使用不同的名称)?
使用common_type
的{{1}}行为更接近于三元运算符的行为(但不使用 (1)
)使用std::decay_t
时的行为:
(2)
这种方法的缺点是什么?这是真的吗,template< typename T >
T declval();
template <class ...T> struct common_type;
template< class... T >
using common_type_t = typename common_type<T...>::type;
template <class T>
struct common_type<T> {
typedef T type;
};
template <class T, class U>
struct common_type<T, U> {
typedef decltype(true ? declval<T>() : declval<U>()) type;
};
template <class T, class U, class... V>
struct common_type<T, U, V...> {
typedef common_type_t<common_type_t<T, U>, V...> type;
};
#include <type_traits>
#include <utility>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunevaluated-expression"
int
main()
{
int i{};
static_assert(std::is_same< int &, decltype((i)) >{});
static_assert(std::is_same< int , std::common_type_t< decltype((i)), decltype((i)) > >{});
static_assert(std::is_same< int &, decltype(true ? i : i) >{});
static_assert(std::is_same< int &, common_type_t< decltype((i)), decltype((i)) > >{});
int && k{};
static_assert(std::is_same< int &&, decltype(k) >{});
static_assert(std::is_same< int , std::common_type_t< decltype(k), decltype(k) > >{});
static_assert(std::is_same< int &&, decltype(true ? std::move(k) : std::move(k)) >{});
static_assert(std::is_same< int &&, common_type_t< decltype(k), decltype(k) > >{});
return 0;
}
#pragma clang diagnostic pop
中的(1)
上下文类型decltype()
应该是可构造的(根本应该至少有一个构造函数)和/或可破坏的吗?
对于非专用的std :: common_type,确定每对T1,T2之间的公共类型的规则正是确定未评估上下文中三元条件运算符的返回类型的规则,其中任意第一个参数类型为bool并使用
T
xvalues of type T1 and T2 (since C++17)
作为第二个和第三个操作数。std::declval<T1>() and std::declval<T2>() (until C++17)
我认为最后一句(The common type is the result of std::decay applied to the type of the ternary conditional (since C++14).
)很可能不只是emphasized
而且since C++14
才公平。否则,即使在 C ++ 17 之后,第一句引用也不会成立,并且会出现一些缺陷。
关于until C++17
问题的should-stdcommon-type-use-stddecay评论中有一些说明,但它只是当前问题的背景信息。
答案 0 :(得分:2)
优点:
template <class T> T&& declval();
它适用于任何类型T
,而简单地返回T
将不适用于不可返回的类型(例如函数,数组)和类型不可破坏(例如私有/受保护/删除的析构函数,抽象基类)。
当然,令人不快的是,common_type<int, int>
最终成为int&&
,然后您需要添加decay
,这会使common_type<int&, int&>
成为int
- 其中也没有意义。这里没有胜利。
最终,我认为我们只需要一些语言功能,在未评估的环境中,它会给我一些类型T
&#34;适用于任何T
,真正为您提供T
(而不是T&&
)。