std :: add_const和类似的用例

Rei*_*ica 25 c++ language-lawyer c++11

某些类型转换<type_traits>也可以使用核心语言语法表达(例如std::add_const<T>::type,/似乎等同于const T).Dtto for std::add_lvalue_reference,也许是其他人.这些类型特征有什么用?

我完全理解标准会提供一个没有它们的"不完整的工具箱",我可以想象以元方式使用,如下所示:

template<typename In, template <typename> class Modifier>
struct Apply {
  typedef typename Modifier<T>::type Out;
};

Apply<int, std::add_const>
Run Code Online (Sandbox Code Playgroud)

是否存在可以在语法上表达的这些特征的任何其他用例,或者它们是否仅仅是"出于完整感"和偶尔的元使用?

Jon*_*ely 23

这些特征来自Boost以及将其添加到标准N1345中的提议引用Andrei Alexandrescu的话说:

"据我所知,用于将对称的说法add_const,add_volatile,add_cv,和add_pointer,但我会赞成消除这些争论.语言提供的等价物都只是简单的和更好的."

同样的提案也给出了这个理由:

作者注:表面上的add_const,add_volatile和add_cv类是无关紧要的,因为,例如,add_const ::类型与T相同常量,对于所有的T(目前这并不适用于功能类型-但发行295个地址本).但是从提升经验是,一些用户已要求这些模板存在于以下原因库:(一)有些用户发现这些更为明确-将特别改造的模板,用户喜欢那种"建于何时"这些模板提供的文档".(b)并非所有用户都知道允许对引用进行资格认证且无效,或者允许对符合cv资格的类型进行cv认证且无效.(c)编译器在对作为参考的类型进行cv限定或者已经具有cv限定符时可以发出警告,可以实现这些模板,以便在这些情况下抑制这些消息.

另外,对于add_reference(add_lvalue_reference在标准中重命名):

作者注:add_reference模板是boost类型特征库背后的原始动机之一.但是,问题106的解决方案使模板显得多余.尽管add_reference可能在无意中在模板代码中创建对引用的引用时抑制编译器警告.

  • `add_ {l,r} value_reference`也可以很好地与`void`一起使用. (4认同)

Jan*_*ann 8

这些特征是为偶尔的元使用而提供的.它使得在元编程中传输有用的cv限定符成为可能.

template<class T,template<class> class Trait>
struct transform
{
  /* working with T creating newT*/

  typedef Trait<newT>::type type;
};

template<class T>
struct special_transform
  : transfrom<T, std::add_const>
{};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,你不能代替std::add_constconst.


Jos*_*son 7

add_const 可用于解决类型扣除冲突.

template <typename T>
class wrapper;

template <typename T>
bool operator==(wrapper<T> const& w, T const& t);
Run Code Online (Sandbox Code Playgroud)

如果我们使用wrapper<T const>以下问题:

wrapper<int const> w = { 42 };
assert(w == 42); // Error: conflicting deduced types
Run Code Online (Sandbox Code Playgroud)

T同时推断为int int const.这可以使用add_const以下方法解决:

template <typename T>
bool operator==(wrapper<T> const& w, add_const_t<T>& t);
Run Code Online (Sandbox Code Playgroud)