本文介绍了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

这种方法有什么缺点?是真的,(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&amp;&amp; declat()for common_type的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 09:27