编译错误:在模板类的模板构造函数中使用emplace_back

huangapple go评论78阅读模式
英文:

Compilation error for emplace_back on templated constructor of a templated class

问题

I am using https://github.com/ben-strasser/fast-cpp-csv-parser for parsing csv. I create a vector of CSVReader objects which I create using emplace_back (since copy, move are deleted). For some reason, the args passed in emplace_back is being read as CSVReader type in the templated constructor of CSVReader.

Reproducable code here: https://godbolt.org/z/Ps11EzbK9 (typed down below as well)

// Type your code here, or load an example.
#include <iostream>
#include <vector>

class LineReader {
public:
  LineReader() = delete;
  LineReader(const LineReader &) = delete;
  LineReader &operator=(const LineReader &) = delete;
  explicit LineReader(const char *file_name) {
    ;
  }
};

template <unsigned column_count>
class CSVReader {
private:
  LineReader in;
public:
  CSVReader() = delete;
  CSVReader(const CSVReader &) = delete;
  CSVReader &operator=(const CSVReader &);

  template <class... Args>
  explicit CSVReader(Args &&... args) : in(std::forward<Args>(args)...) {
  }
};

int main()
{
    std::vector <CSVReader<12>> vec;
    vec.emplace_back("hello world");
    return 0;
}

Any idea what am I missing?

英文:

I am using https://github.com/ben-strasser/fast-cpp-csv-parser for parsing csv. I create a vector of CSVReader objects which I create using emplace_back (since copy, move are deleted). For some reason, the args passed in emplace_back is being read as CSVReader type in the templated constructor of CSVReader.

Reproducable code here: https://godbolt.org/z/Ps11EzbK9 (typed down below as well)

// Type your code here, or load an example.
#include &lt;iostream&gt;
#include &lt;vector&gt;

class LineReader {
public:
  LineReader() = delete;
  LineReader(const LineReader &amp;) = delete;
  LineReader &amp;operator=(const LineReader &amp;) = delete;
  explicit LineReader(const char *file_name) {
    ;
  }
};

template &lt;unsigned column_count&gt;
class CSVReader {
private:
  LineReader in;
public:
  CSVReader() = delete;
  CSVReader(const CSVReader &amp;) = delete;
  CSVReader &amp;operator=(const CSVReader &amp;);

  template &lt;class... Args&gt;
  explicit CSVReader(Args &amp;&amp;... args) : in(std::forward&lt;Args&gt;(args)...) {
  }
};

int main()
{
    std::vector &lt;CSVReader&lt;12&gt;&gt; vec;
    vec.emplace_back(&quot;hello world&quot;);
    return 0;
}

Any idea what am I missing?

答案1

得分: 2

你的问题在于CSVReaderstd::vector中无法使用。当std::vector增长时,它通过使用你的类的移动/复制构造函数将旧缓冲区移动/复制到一个新的更大缓冲区。问题就在这里,CSVReader没有移动或复制构造函数。

通常解决这个问题的方法是使用一层间接,使用std::vector<std::vector<std::unique_ptr<CSVReader<12>>>>的向量。然后,你可以像这样向向量添加元素:vec.push_back(std::make_unique<CSVReader<12>>("hello world"));,就像在这个实例中看到的那样。

英文:

Your issue is that CSVReader is not usable in a std::vector. When std::vector grows, it moves/copys the old buffer in to a new larger buffer by using the move/copy constrcutor of your class. Therein lies the problem, CSVReader does not have a move or copy constructor.

The way normally solve this is to use a layer of indirection and have a vector of std::vector&lt;std::unique_ptr&lt;CSVReader&lt;12&gt;&gt;&gt;. Then you would add elements to the vector like vec.push_back(std::make_unique&lt;CSVReader&lt;12&gt;&gt;(&quot;hello world&quot;)); as seen in this live example.

答案2

得分: 0

发生的情况是,将元素添加到"vec"时试图复制您的CSVReader,但该类没有显式的复制构造函数。然后编译器遇到(唯一的)构造函数模板,在初始化列表中将参数(在这里是要复制的CSVReader)传递给"in"成员的构造过程,但是"in"成员无法处理CSVReader(它的唯一构造函数接受一个char*)。

解决方案:编写一个干净的复制构造函数,正确初始化"in"。

英文:

what happens is, that the adding of an element to "vec" tries to make a copy of your CSVReader, but that does not have an explicit copy constructor.
Then the compiler stumbles across the (only) Constructor template, which passes the arguments (here: the CSVReader to be copied) in the initialisation list into the construction of the "in" member, which of cause cannot handle a CSVReader (its only constructor takes a char*).

Solution: write a clean copy constructor, that properly initialises "in".

huangapple
  • 本文由 发表于 2023年3月3日 20:59:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/75627395.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定