c ++中的模板通用引用无法编译

时间:2018-05-24 22:53:48

标签: c++ c++14 forwarding-reference

我无法理解为什么我的代码在这里没有编译。我从标准库中获取了大量错误消息,与

一致
main3.cpp:10:20:   required from ‘void addAndCout(T&&) [with T = const char (&)[11]]’
main3.cpp:20:28:   required from here
/usr/include/c++/5/bits/alloc_traits.h:450:27: error: forming pointer to reference type ‘const char (&)[11]’
       using pointer = _Tp*;
                           ^
/usr/include/c++/5/bits/alloc_traits.h:453:39: error: forming pointer to reference type ‘const char (&)[11]’
       using const_pointer = const _Tp*;

这对我来说没有意义,因为我认为T&&amp ;,当T没有被推断时,是一个通用引用,它应该能够绑定到右值或左值。这个例子发布的是我试图复制Scott Meyer"有效的现代C ++"我正在阅读有关通用参考的内容。 Photo of example from the book

我只是想知道为什么这不会编译或我在这里失踪的内容,因为据我所知,它与示例实际上是一样的。

#include <iostream>
#include <vector>
#include <string>
using std::cout;
using std::endl;

template<typename T>
void addAndCout(T &&name)
{
    std::vector<T> v;

    cout << name << endl;
    v.emplace_back(std::forward<T>(name));
}

int main(int argc, char **argv)
{
    std::string name {"test"};

    addAndCout(std::string("rvalue")); // FINE      move rvalue instead of copying it
    addAndCout("New string");          // ERROR     make a new string instead of copying
    addAndCout(name);                  // ERROR     copy lvalue
}

2 个答案:

答案 0 :(得分:3)

不能有vector个引用,也不能有C样式数组的向量。当参数是左值和/或C样式数组时,行std::vector<T> v;无法编译。

您的代码与本书的不同之处在于您执行std::vector<T> v;而本书却没有。

要支持使用addAndCout(name);,您可以将矢量定义更改为:

std::vector< typename std::remove_cv<typename std::remove_reference<T>::type>::type > v;

remove_cv是因为不能有const对象的矢量。)

为了支持C风格的数组,添加额外的重载是最简单的:

template<typename T, size_t N>
void addAndCout(T (&name)[N])
{
     // do whatever...
}

答案 1 :(得分:1)

  • 执行addAndCout(std::string("rvalue"));时,这是右值 引用和模板参数T是std :: string和 this::std::vector<std::string> v;这是有效的。
  • 但是当你做addAndCout("New string"); T被推断为对const char数组的引用,而你不能有引用的向量
  • 当你做addAndCout(name);时,你正在传递l值ref,和 T变为std::string&且类似,你不能有引用的向量。