首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >T declval()代替T && declval()用于common_type

T declval()代替T && declval()用于common_type
EN

Stack Overflow用户
提问于 2016-02-20 16:32:29
回答 1查看 673关注 0票数 4

使用表单中声明的std::declval不是更好吗:

代码语言:javascript
复制
template< class T > T declval(); // (1)

然后是现在的一个:

代码语言:javascript
复制
template< class T > T && declval(); // (2)

对于std::common_type (可能仅为当前目的使用不同的名称)?

common_type使用(1)的行为更接近三元操作符的行为(但不使用 std::decay_t),而不是使用(2)时的行为。

代码语言:javascript
复制
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()上下文类型,T应该是可构造的(即至少应该有一个构造函数)和/或可销毁吗?

参考文章说:

对于非专门化的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::common_type问题的澄清,但这只是当前问题的背景信息。

EN

回答 1

Stack Overflow用户

发布于 2016-02-21 21:16:08

以下优点:

代码语言:javascript
复制
template <class T> T&& declval();

它适用于任何类型的T,而简单返回T则不适用于不可返回的类型(例如函数、数组)和不可销毁的类型(例如私有/受保护/删除的析构函数、抽象基类)。

当然,最大的优势是common_type<int, int>最终是int&&,然后您需要添加decay,这使得common_type<int&, int&>成为int --这也没有意义。这里根本就没有胜利。

最终,我认为我们只需要一些语言特性,在未评估的上下文中,它是“给我一个T类型的东西”,它适用于任何T,它确实给了您一个T (而不是T&&)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35525912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档