c ++ 11

时间:2016-06-06 15:09:21

标签: c++ c++11 typeof

我知道:

  • typeof是gcc扩展名,不属于C ++标准。

问题:

  1. C ++ 11中是否弃用了typeof这个词?换句话说,在使用C ++ 11时,是否允许它仍然用作gcc扩展名?
  2. typeof替换每个decltype会产生相同的代码行为是否正确?
  3. 假设我有template<typename T> class wrapper。声明wrapper_some_field的最佳方式是什么,它等同于:Wrapper<typeof(some_field)> wrapper_some_field

2 个答案:

答案 0 :(得分:11)

  

C ++ 11中是否弃用了typeof这个词?换句话说,在使用C ++ 11时,是否允许它仍然用作gcc扩展名?

不是已弃用。它从未作为关键字存在。 gcc suggests,如果您使用-std=c++**进行编译,则使用__typeof__

  

typeof替换每个decltype产生相同的代码行为是否正确?

没有。例如,给定:

int& foo();

decltype(foo())int&__typeof__(foo())int

  

假设我有template<typename T> class wrapper。 [...]

您可以编写wrapper<std::remove_reference_t<decltype(some_field)>> wrap{some_field},但编写构造函数模板会更清晰:

template <class T> wrapper<T> make_wrapper(T const& val) { return {val}; }
auto wrap = make_wrapper(some_field);

或者,转发:

template <class T>
wrapper<std::decay_t<T>> make_wrapper(T&& val) {
    return {std::forward<T>(val)};
}

虽然在C ++ 17中你根本不会这样做,只会使用类模板参数演绎:

template <class T> struct wrapper { T t; };
template <class T> wrapper(T) -> wrapper<T>;
auto wrap = wrapper{42}; // wrap is a wrapper<int>

在C ++ 20中,你甚至不需要演绎指南。

答案 1 :(得分:4)

#define typeof(...) std::remove_reference_t<decltype(__VA_ARGS__)>;

但是,如果要为类型T创建存储,在C ++ 11中执行此操作的方法是使用std::decay_t,或者在某些情况下编写自己的存储C的扩展名将样式数组转换为std::array

Wrapper<std::decay_t<T>> wrapper_some_field;

如果你想传递Wrapper适合存储在其中的类型。

decay删除引用,将函数转换为指向函数的指针,将T数组转换为指向T的指针,然后删除顶级constvolatile。这些操作类似于将事物作为“衰减到指针/值”操作的一部分传递给函数时发生的操作。

结果是“适合存储”的类型。如上所述,我希望将int[4]衰减为std::array<int,4>,但您不能所有内容