我收到了所有编译器的意外结果(GCC 4.7.2,GCC 4.8.0 beta,ICC 13.0.1,Clang 3.2,VC10): #include <type_traits> int main() { // This will fire static_assert( std::is_same<decltype("Hello"), char const[6]>::value, "Error!" ); } 我希望上面的编译时间断言不会触发,但它确实如此。 毕竟,这不是(如预期): #include <type_traits> int main() { char const hello[6] = "Hello"; // This will not fire static_assert( std::is_same<decltype(hello), char const[6]>::value, "Error!" ); } 那么根据C ++ 11标准, decltype("Hello")的结果是什么(高度赞赏引用)? 我应该如何比较以便上面的编译时间断言不会触发?
std::declval是一个编译时间实用程序,用于构buildexpression式以确定其types。 它是这样定义的: template< class T > typename std::add_rvalue_reference<T>::type declval() noexcept; 这不是更简单吗? template< class T > T declval() noexcept; 引用返回types的优点是什么? 不应该叫做declref ? 我发现的最早的历史例子是n2958 ,它调用函数的value()但总是返回一个引用。 注意, decltype的操作数不需要有一个可访问的析构函数,也就是说,它不是在语义上被检查为一个完整的expression式。 template< typename t > t declprval() noexcept; class c { ~ c (); }; decltype ( declprval< c >() ) * p = nullptr; // OK
我有一些我不能修改的类。 每个都有一个拷贝构造函数,至less有一个其他的构造函数和一个返回值的函数foo() 。 我想创build一个可以从这些类派生出来的类模板,并且有一个与foo()的返回types相同types的数据成员(抱歉,如果我有一些术语错误)。 换句话说,我想要一个类模板 template<typename T> class C : public T { footype fooresult; }; footype是T::foo()的返回types。 如果基类都拥有默认的构造函数,我可以这样做 decltype(T().foo()) fooresult; (在GCC中具有C ++ 0xfunction),但除了复制构造函数之外,类没有任何特殊的构造函数。 GCC也不允许decltype(this->foo()) ,尽pipe显然有可能这将被添加到C ++ 0x标准 – 有谁知道这是多么可能吗? 我觉得应该可以沿着decltype(foo())或decltype(T::foo())的方式来做一些事情,但这些似乎不起作用:GCC给出了一个错误,表单cannot call member function 'int A::foo()' without object 。 当然,我可以有一个额外的模板参数footype ,甚至Ttypes的非类参数,但有什么办法可以避免这种情况?
我发现这样的代码: template <typename T, typename T1> auto compose(T a, T1 b) -> decltype(a + b) { return a+b; } 我想到了所有的细节,这些细节对我来说是新的,但是其中之一。 请告诉我,我在哪里可以阅读,在function标题中箭头运算符( -> )是什么意思? 我想纯粹逻辑上,那->运算符决定一个types,这将通过auto得到,但我想得到这个直,但不能find信息。
我在这里find的代码看起来像这样: auto f(T& t, size_t n) -> decltype(t.reserve(n), void()) { .. } 在我读的所有文档中,我被告知decltype被签名为: decltype( entity ) 要么 decltype( expression ) 而且在任何地方都没有第二个论点。 至less这是cppreference指向的内容。 这是decltype的第二个参数吗? 如果是这样,它是做什么的?
正如我在C ++ 11中所理解的, decltype(expression)用于推导给定expression式的完全相同types。 但是当expression式本身被放入括号中时,则推导types是左值对expression式types的引用 。 例如: int x; decltype(x) y = x; 相当于int y = x; 但, int x; decltype((x)) y = x; 相当于int& y = x; 。 分别 decltype(auto) f1() { int x = 0; return x; // decltype(x) is int, so f1 returns int } 但 decltype(auto) f2() { int x = […]
在c ++ 14中引入了decltype(auto)成语。 通常它的用途是允许auto声明在给定的expression式上使用decltype规则 。 search成语的“好”用法的示例我只能想到像下面这样的东西( Scott Meyers ),即函数的返回types推理 : template<typename ContainerType, typename IndexType> // C++14 decltype(auto) grab(ContainerType&& container, IndexType&& index) { authenticateUser(); return std::forward<ContainerType>(container)[std::forward<IndexType>(index)]; } 有没有其他的例子,这个新的语言function是有用的? 我最初的例子是这样的: decltype(auto) Example(int const& i) { return i; // return type will be "int const&" }
我在理解C ++ 0x中std::result_of的需求时遇到了一些麻烦。 如果我理解正确, result_of用于获取调用具有某些types参数的函数对象的结果types。 例如: template <typename F, typename Arg> typename std::result_of<F(Arg)>::type invoke(F f, Arg a) { return f(a); } 我真的没有看到与以下代码的区别: template <typename F, typename Arg> auto invoke(F f, Arg a) -> decltype(f(a)) //uses the f parameter { return f(a); } 要么 template <typename F, typename Arg> auto invoke(F f, Arg a) -> decltype(F()(a)); […]
编辑,为了避免混淆: decltype不接受两个参数。 查看答案。 在编译期间,可以使用以下两个结构来检查typesT上成员函数的存在: // Non-templated helper struct: struct _test_has_foo { template<class T> static auto test(T* p) -> decltype(p->foo(), std::true_type()); template<class> static auto test(…) -> std::false_type; }; // Templated actual struct: template<class T> struct has_foo : decltype(_test_has_foo::test<T>(0)) {}; 我认为这个想法是在检查成员函数的存在时使用SFINAE,所以在p->foo()无效的情况下,只定义返回std::false_type的test的椭圆版本。 否则,第一个方法被定义为T* ,并将返回std::true_type 。 实际的“开关”发生在第二个类中,它inheritance自test返回的types。 与is_same等不同的方法相比,这看起来很聪明和“轻量级”。 有两个参数的decltype首先让我感到惊讶,因为我认为它只是得到了一个expression式的types。 当我看到上面的代码时,我认为它是“试图编译expression式,并总是返回第二种types,如果expression式编译失败,则失败”(所以隐藏这个特殊化; SFINAE)。 但: 然后我想我可以用这个方法来写任何“有效的expression式”检查器,只要它依赖于某种types的T 例: … template<class T> static auto […]
我正在阅读C ++ Primer,当expression式产生一个对象types,并产生一个对象的引用types时,我不太明白。 我引用这本书: 当我们将decltype应用于不是variables的expression式时,我们得到expression式产生的types。 一般来说,decltype会返回一个expression式的引用types,这些expression式会产生可以位于赋值左侧的对象。 考虑下面的代码: int i = 3, *ptr = &i, &ref = i; decltype(ref + 0) j; 在上面的代码中,expression式“ref + 0”产生了ref引用的对象的值i和0的附加值的固有操作。因此,按照第一个规则,expression式产生一个inttypes。 但是按照第二条规则,因为expression式产生了一个可以站在赋值左边的对象的types(在本例中为int),decltype不应该产生一个int(int&)types的引用吗? 这本书还说,下面的代码 decltype(*ptr) k; k的types是int&而不是int,expression式的结果types。 它还表示,像下面的代码中的分配expression式 decltype(a = b) l; l将在赋值操作的左侧具有对象的引用types。 我们如何知道哪些expression式产生对象types,哪些产生对对象types的引用?