使用不是更好吗std::declval
声明形式:
template< class T > T declval(); // (1)
然后是当前的:
template< class T > T && declval(); // (2)
for std::common_type
(可能仅出于当前目的而使用不同的名称)?
的行为common_type
using (1)
更接近于行为三元运算符 (but 不使用 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
实例 http://coliru.stacked-crooked.com/a/5db372e89a3ac55b.
这种方法有什么缺点?这是真的吗?(1)
in decltype()
上下文类型T
应该是可构造的(根本,即应该至少有一个构造函数)和/或可破坏?
参考文章 http://en.cppreference.com/w/cpp/types/common_type said:
对于非专门化的 std::common_type,确定每对 T1、T2 之间的公共类型的规则正是在未计算的上下文中确定三元条件运算符的返回类型的规则,其中任意第一个参数为 bool 类型,并且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
但是也until C++17
公平起见。否则,即使在之后,引用的第一句也不会成立C++17并且会存在一些缺陷。
有一些澄清应该-std 通用类型-使用-std 衰减 https://stackoverflow.com/questions/21975812/关于的评论std::common_type
问题,但这只是当前问题的背景信息。