T declval()而不是T&& declat()for common_type [英] T declval() instead of T && declval() for common_type

查看:218
本文介绍了T declval()而不是T&& declat()for common_type的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不是最好使用以下形式声明的 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

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

Live example

这种方法有什么缺点?是真的,(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?

参考文章说:


非专用的std :: common_type,用于确定每对T1,T2之间的公共类型的规则正是用于确定未评估上下文中的三元条件运算符的返回类型的规则,具有类型为bool的任意第一个参数,并且具有类型T1和T2的x值(自C ++ 17开始) std :: declval< T1>()和std :: declval< T2>直到C ++ 17)作为第二个和第三个操作数。 常见类型是std :: decay应用于三元条件类型的结果(自C ++ 14开始)。

For non-specialized std::common_type, the rules for determining the common type between every pair T1, T2 are exactly the rules for determining the return type of the ternary conditional operator in unevaluated context, with arbitrary first argument of type bool and with xvalues of type T1 and T2 (since C++17) std::declval<T1>() and std::declval<T2>() (until C++17) as the second and the third operands. The common type is the result of std::decay applied to the type of the ternary conditional (since C++14).

我认为很可能最后一句(强调)应该不只是 ++ 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&amp;&amp; declat()for common_type的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆