没有匹配的构造函数来初始化 MyClassName
No matching constructor for initialization of MyClassName
我有一个 class,在截取的代码中我粘贴了我认为有问题的部分。
class SubtreeExplorer : public AbstractTask {
public:
SubtreeExplorer(Threadpool& tp, SudokuBoard&& sudoku)
: tp(tp), sudoku(std::move(sudoku)) {}
...
private:
Threadpool& tp;
SudokuBoard sudoku;
bool sudoku_backtracking_search(SudokuBoard& s) {
...
while(...){
...
// let another thread explore the subtree
tp.submit(make_shared<SubtreeExplorer>(tp, SudokuBoard(sudoku)));
}
}
};
当我尝试编译它时出现错误:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:4325:5: error: static_assert failed due to requirement 'is_constructible<SubtreeExplorer,
Threadpool &, SudokuBoard &>::value' "Can't construct object in make_shared"
static_assert( is_constructible<_Tp, _Args...>::value, "Can't construct object in make_shared" );
我正在使用 VS Code,在 IDE 中没有突出显示任何错误。
问题可能是由 make_shared
引起的,但我无法弄清楚构造函数中的内容 ok 导致它的 SubtreeExplorer class。
Sudokuboard(sudoku)
returns 一块新板,来自给定的板,几乎没有修改。我希望将这个新板移动到新的子树资源管理器中。
查看google,我写的构造函数应该把板子移进去了,但我仍然得到我写的编译错误,加上一长串难以阅读的注释:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:2259:9: note: in instantiation of function template specialization
'std::__1::__compressed_pair_elem<SubtreeExplorer, 1, false>::__compressed_pair_elem<Threadpool &, SudokuBoard &, 0, 1>' requested here
_Base2(__pc, _VSTD::move(__second_args),
^ /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:3672:16: note: in instantiation of function template specialization
'std::__1::__compressed_pair<std::__1::allocator<SubtreeExplorer>, SubtreeExplorer>::__compressed_pair<std::__1::allocator<SubtreeExplorer> &,
Threadpool &, SudokuBoard &>' requested here
: __data_(piecewise_construct, _VSTD::forward_as_tuple(__a),
^ /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:4331:26: note: in instantiation of function template specialization
'std::__1::__shared_ptr_emplace<SubtreeExplorer, std::__1::allocator<SubtreeExplorer>
>::__shared_ptr_emplace<Threadpool &, SudokuBoard &>' requested
here
::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...);
^ /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:4710:29: note: in instantiation of function template specialization
'std::__1::shared_ptr<SubtreeExplorer>::make_shared<Threadpool &, SudokuBoard &>' requested here
return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...);
^ src/sudoku_parallel.cpp:119:13: note: in instantiation of function template specialization 'std::__1::make_shared<SubtreeExplorer, Threadpool &, SudokuBoard
&>' requested here tp.submit(make_shared<SubtreeExplorer>(tp, sudoku));
^ src/sudoku_parallel.cpp:41:3: note: candidate constructor not viable: no known conversion from 'SudokuBoard' to 'SudokuBoard &&' for 2nd argument SubtreeExplorer(Threadpool& tp, SudokuBoard&& sudoku) ^ src/sudoku_parallel.cpp:39:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided class SubtreeExplorer : public AbstractTask {
^ src/sudoku_parallel.cpp:39:7: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided
这让我觉得我向构造函数传递了错误数量的参数,即使它有两个参数并且我传递了两个参数,一个线程池和一个数独板。
在主体中,SubtreeExplorer 的创建类似于 sudoku_backtracking_search 函数的主体:
int main() {
...
SubokuBoard sudoku(filepath);
tp.submit(make_shared<SubtreeExplorer>(tp, sudoku));
...
}
编辑:
tp 是一个线程池,其提交方法具有以下签名:
bool submit(std::shared_ptr<AbstractTask> task);
AbstractTask class 如下:
struct AbstractTask {
virtual ~AbstractTask() = default;
virtual void run() = 0;
};
构造函数采用对 SudokuBoard
的右值引用,但您将其传递给左值。这就是您收到错误的原因;左值引用不能隐式转换为右值引用,因此调用失败。
您可以使用以下任一选项更正问题:
最好的选择是更改 SubtreeExplorer
构造函数以按值接受第二个参数,这允许调用者移动构造或复制构造它,具体取决于是否他们需要保留一份论证副本。您可以在需要时获得移动语义的好处,但副本仍然可以接受。
(假设 SudokuBoard
类型有一个复制构造函数。)
SubtreeExplorer(Threadpool& tp, SudokuBoard sudoku)
: tp(tp), sudoku(std::move(sudoku)) {}
通过应用 std::move()
:
将右值引用传递给命名变量
SubokuBoard sudoku(filepath);
tp.submit(make_shared<SubtreeExplorer>(tp, std::move(sudoku)));
完全删除命名变量并传递一个临时变量:
tp.submit(make_shared<SubtreeExplorer>(tp, SudokuBoard{filepath}));
我建议实施选项 1,但是如果您不需要在此之后使用 sudoku
变量,那么 也 实施选项 2 或 3 =18=] 调用 -- 否则你将进行无意义的复制。
我有一个 class,在截取的代码中我粘贴了我认为有问题的部分。
class SubtreeExplorer : public AbstractTask {
public:
SubtreeExplorer(Threadpool& tp, SudokuBoard&& sudoku)
: tp(tp), sudoku(std::move(sudoku)) {}
...
private:
Threadpool& tp;
SudokuBoard sudoku;
bool sudoku_backtracking_search(SudokuBoard& s) {
...
while(...){
...
// let another thread explore the subtree
tp.submit(make_shared<SubtreeExplorer>(tp, SudokuBoard(sudoku)));
}
}
};
当我尝试编译它时出现错误:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:4325:5: error: static_assert failed due to requirement 'is_constructible<SubtreeExplorer,
Threadpool &, SudokuBoard &>::value' "Can't construct object in make_shared"
static_assert( is_constructible<_Tp, _Args...>::value, "Can't construct object in make_shared" );
我正在使用 VS Code,在 IDE 中没有突出显示任何错误。
问题可能是由 make_shared
引起的,但我无法弄清楚构造函数中的内容 ok 导致它的 SubtreeExplorer class。
Sudokuboard(sudoku)
returns 一块新板,来自给定的板,几乎没有修改。我希望将这个新板移动到新的子树资源管理器中。
查看google,我写的构造函数应该把板子移进去了,但我仍然得到我写的编译错误,加上一长串难以阅读的注释:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:2259:9: note: in instantiation of function template specialization
'std::__1::__compressed_pair_elem<SubtreeExplorer, 1, false>::__compressed_pair_elem<Threadpool &, SudokuBoard &, 0, 1>' requested here
_Base2(__pc, _VSTD::move(__second_args),
^ /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:3672:16: note: in instantiation of function template specialization
'std::__1::__compressed_pair<std::__1::allocator<SubtreeExplorer>, SubtreeExplorer>::__compressed_pair<std::__1::allocator<SubtreeExplorer> &,
Threadpool &, SudokuBoard &>' requested here
: __data_(piecewise_construct, _VSTD::forward_as_tuple(__a),
^ /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:4331:26: note: in instantiation of function template specialization
'std::__1::__shared_ptr_emplace<SubtreeExplorer, std::__1::allocator<SubtreeExplorer>
>::__shared_ptr_emplace<Threadpool &, SudokuBoard &>' requested
here
::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...);
^ /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:4710:29: note: in instantiation of function template specialization
'std::__1::shared_ptr<SubtreeExplorer>::make_shared<Threadpool &, SudokuBoard &>' requested here
return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...);
^ src/sudoku_parallel.cpp:119:13: note: in instantiation of function template specialization 'std::__1::make_shared<SubtreeExplorer, Threadpool &, SudokuBoard
&>' requested here tp.submit(make_shared<SubtreeExplorer>(tp, sudoku));
^ src/sudoku_parallel.cpp:41:3: note: candidate constructor not viable: no known conversion from 'SudokuBoard' to 'SudokuBoard &&' for 2nd argument SubtreeExplorer(Threadpool& tp, SudokuBoard&& sudoku) ^ src/sudoku_parallel.cpp:39:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided class SubtreeExplorer : public AbstractTask {
^ src/sudoku_parallel.cpp:39:7: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided
这让我觉得我向构造函数传递了错误数量的参数,即使它有两个参数并且我传递了两个参数,一个线程池和一个数独板。
在主体中,SubtreeExplorer 的创建类似于 sudoku_backtracking_search 函数的主体:
int main() {
...
SubokuBoard sudoku(filepath);
tp.submit(make_shared<SubtreeExplorer>(tp, sudoku));
...
}
编辑: tp 是一个线程池,其提交方法具有以下签名:
bool submit(std::shared_ptr<AbstractTask> task);
AbstractTask class 如下:
struct AbstractTask {
virtual ~AbstractTask() = default;
virtual void run() = 0;
};
构造函数采用对 SudokuBoard
的右值引用,但您将其传递给左值。这就是您收到错误的原因;左值引用不能隐式转换为右值引用,因此调用失败。
您可以使用以下任一选项更正问题:
最好的选择是更改
SubtreeExplorer
构造函数以按值接受第二个参数,这允许调用者移动构造或复制构造它,具体取决于是否他们需要保留一份论证副本。您可以在需要时获得移动语义的好处,但副本仍然可以接受。(假设
SudokuBoard
类型有一个复制构造函数。)SubtreeExplorer(Threadpool& tp, SudokuBoard sudoku) : tp(tp), sudoku(std::move(sudoku)) {}
通过应用
将右值引用传递给命名变量std::move()
:SubokuBoard sudoku(filepath); tp.submit(make_shared<SubtreeExplorer>(tp, std::move(sudoku)));
完全删除命名变量并传递一个临时变量:
tp.submit(make_shared<SubtreeExplorer>(tp, SudokuBoard{filepath}));
我建议实施选项 1,但是如果您不需要在此之后使用 sudoku
变量,那么 也 实施选项 2 或 3 =18=] 调用 -- 否则你将进行无意义的复制。