英文:
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 <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?
答案1
得分: 2
你的问题在于CSVReader
在std::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<std::unique_ptr<CSVReader<12>>>
. Then you would add elements to the vector like vec.push_back(std::make_unique<CSVReader<12>>("hello world"));
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".
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论