问题描述
不是最好使用以下形式声明的 std :: declval :
Isn't it better to use std::declval declared in form:
template< class T > T declval(); // (1)
当前一个:
template< class T > T && declval(); // (2)
std :: common_type $ c $ <>
common_type 的行为使用(1)更接近三元运算符的行为(但不使用 std :: decay_t :
Behaviour of common_type using (1) is closer to the behaviour of the ternary operator (but not using std::decay_t) than the behaviour when using (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()上下文类型 code>应该是可构造的(至少应该有至少一个构造函数)和/或可破坏的?
What are downsides of this approach? Is it true, that for (1) in decltype() context type T should be constructible (at all, i.e. should have at least one constructor) and/or destructible?
说:
我认为很可能最后一句(强调)应该不只是 ++ 14 ,而且还要,直到C ++ 17 公平。否则第一句引用将不会成立,即使在 C ++ 17 之后,会出现一些缺陷。
I think it is very likely the last sentence (emphasized) should be not just since C++14 but also until C++17 to be fair. Otherwise 1st sentence of cite will not holds even after C++17 and some defect will be present.
href =http://stackoverflow.com/questions/21975812/> should-stdcommon-type-use-stddecay 关于 std :: common_type 问题的意见,但它只是当前问题的背景信息。
There is some clarification in should-stdcommon-type-use-stddecay comments regarding std::common_type problems, but it is just background information for the current question.
推荐答案
template <class T> T&& declval();
是适用于任何类型 T ,而简单返回 T 将不适用于不可返回的类型(例如函数,数组)和不可销毁的类型(例如私有/保护/删除析构函数,抽象基类)。
is that it works for any type T, whereas simply returning T will not work for types that are no returnable (e.g. functions, arrays) and types that are not destroyable (e.g. private/protected/deleted destructor, abstract base classes).
当然,distC的优点是 common_type< int,int> int&&& ,然后你需要添加 decay ,它使 common_type< int& / code> be int - 这也没有意义。这里没有胜利。
Of course, the distandvantage is that common_type<int, int> ends up being int&&, and then you need to add decay which makes common_type<int&, int&> be int - which doesn't make sense either. There's just no win here.
最后,我认为我们只需要一些语言特性,类型 T 适用于任何 T ,真的 $ c> T (而不是 T&& )。
Ultimately, I think we just need some language feature that, in an unevaluated context, is "give me something of type T" that works for any T, that really gives you a T (and not a T&&).
这篇关于T declval()而不是T&& declat()for common_type的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!