【发布时间】:2012-03-19 14:38:21
【问题描述】:
首先,我知道 stackoverflow 上已经有类似的问题(this、this 和 this one),这就是为什么我理解我的问题的原因。不幸的是,这并不能帮助我解决它。
虽然上述问题都与默认的无参数构造函数有关,但我在使用具有默认值的 双参数构造函数时遇到了问题 - 我试图构造一个仅调用构造函数的对象给定的第一个值,它被解析为函数声明而不是对象。
这是我的代码的一些 sn-ps(我重命名了类名,因为它们很长且不相关):
class algoContainer{
public:
algoContainer(algo1Virtual &alg1 = algo1Concrete::emptyInstance(),
algo2Virtual &alg2 = algo2Concrete::instance());
someUsefulFunction();
};
class algo1Concrete : public algo1Virtual{
private:
algo1Concrete();
public:
static algo1Concrete &emptyInstance(); // "empty" instance treated
// specifically
// -- uses private no arg constructor
algo1Concrete(const std::vector<data> &myData); // construcotr
};
class algo1Virtual{
// ... all functions virtual, no implementations ...
};
// ... similar for algo2Virtual/Concrete ...
Concrete 类中的所有函数都实现了,而Virtual 类中的所有函数都没有实现(构造函数和析构函数除外)。
所以,我现在的问题是我想做一些类似的事情:
std::vector <data> workData;
// fill workData
algoContainer myAC(algo1Concrete(workData));
myAC.someUsefulFunction(); // this line gives compile error
漂亮,可爱,优雅,但它不起作用(错误与我linked的所有问题相同)。我发现这个forum-tutorial 确实将该问题称为最令人烦恼的解析,但它的解决方案(在参数周围加上括号)并不能解决问题(它是一长串错误消息这种情况,但如果有帮助,我可以稍后在问题中对其进行编辑 - 这些都与继承虚函数有关)。
如果我使用带有默认所有参数的构造函数,我已经测试了我的代码,即使我只是单独构造第一个参数:
std::vector <data> workData;
// fill workData
algo1Concrete myA1(workData);
algoContainer myAC(myA1);
myAC.someUsefulFunction(); // now it works fine
algoContainer myAC2;
myAC2.someUsefulFunction(); // this also works
我可以按原样使用代码,但如果有人能给我一个更优雅的解决方案来解决我现在正在使用的问题,我将不胜感激。
EDIT:当我修复最令人头疼的解析时收到的错误消息
如果我使用带括号的代码:
algoContainer myAC((algo1Concrete(workData)));
我的错误是:
/some_path/main.cpp:47:65: error: no matching function for call to ‘algoContainer::algoContainer(algo1Concrete)’
/some_path/main.cpp:47:65: note: candidates are:
/some_path/algo/algocont.h:45:5: note: algoContainer::algoContainer(algo1Virtual&, algo2Virtual&)
/some_path/algo/algocont.h:45:5: note: no known conversion for argument 1 from ‘algo1Concrete’ to ‘algo1Virtual&’
/some_path/algo/algocont.h:36:7: note: algoContainer::algoContainer(const algoContainer&)
/some_path/algo/algocont.h:36:7: note: no known conversion for argument 1 from ‘algo1Concrete’ to ‘const algoContainer&’
为了便于阅读,我重命名了路径并插入了示例文件和类名(与上面相同)。只是备注:line 45 是相关构造函数的定义。另一方面,line 36 是行class algoContainer。
我也试过这段代码:
algoContainer myDect((algo1Virtual)(algo1Concrete(workData)));
然后错误就完全不同了:
/some_path/main.cpp:47:86: error: cannot allocate an object of abstract type ‘algo1Virtual’
/some_path/algo/alg1/algo1virtual.h:31:7: note: because the following virtual functions are pure within ‘algo1Virtual’:
/some_path/algo/alg1/algo1virtual.h:42:8: note: virtual algo1Virtual::~algo1Virtual()
/some_path/algo/alg1/algo1virtual.h:39:18: note: virtual void algo1Virtual::someAlgo1Function(std::vector<data>&)
/some_path/main.cpp:47:87: error: no matching function for call to ‘algoContainer::algoContainer(algo1Virtual)’
/some_path/main.cpp:47:87: note: candidates are:
/some_path/algo/algocont.h:45:5: note: algoContainer::algoContiner(algo1Virtual&, algo2Virtual&)
/some_path/algo/algocont.h:45:5: note: no known conversion for argument 1 from ‘algo1Virtual’ to ‘algo1Virtual&’
/some_path/algo/algocont.h:36:7: note: algo1Virtual::algo1Virtual(const algo1Virtual&)
/some_path/algo/algocont.h:36:7: note: no known conversion for argument 1 from ‘algo1Virtual’ to ‘const algo1Virtual&’
希望这会有所帮助。
【问题讨论】:
-
你能告诉我们你从
algoContainer myAC((algo1Concrete(workData)));得到的错误吗? -
正如Kerrek 提到的,这是一个最令人烦恼的解析 问题。如果您在使用括号消除歧义时遇到错误,则错误消息将有助于解决问题。
-
@Akanksh 我知道这是一个很长的问题,但我提到的最后一个链接详细解释了最令人头疼的解析,我在问这个问题时就知道了。我从来没有在我的 Q 中明确使用过“最令人烦恼的解析”这个词,但现在我已经编辑了它并将它添加到问题的标签中。
-
@penelope 抱歉抢先使用该链接。我认为这个问题可能是由于 algoContainer 构造函数将输入作为非常量引用,它不能绑定到匿名临时对象。您将需要命名变量,或通过右值引用获取参数,并将 algoConcrete “移动”到其中。本质上,想想谁“拥有”这些论点,以及他们的一生应该是怎样的。
标签: c++ constructor function-declaration most-vexing-parse