First of, I know there are similar questions already on stackoverflow (this, this and this one) and that is why I understand the why of my problem. Unfortunately, that doesn't help me to solve it.
While the above questions are all concerning the default, no-parameter constructor, I have a problem while using a two parameter constructor with default values - I tried to construct an object calling the constructor with only the first value given, and it is parsed as a function declaration instead of an object.
Here are some snippets of my code (I renamed the class names because they're long and not relevant):
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 ...
All the functions in the Concrete
classes are implemented, while none of them in the Virtual
classes are (except the constructors and the destructors).
So, my problem now is that I want to do something like:
std::vector <data> workData;
// fill workData
algoContainer myAC(algo1Concrete(workData));
myAC.someUsefulFunction(); // this line gives compile error
Nice, cute and ellegant, but it does not work (error the same as all the questions I linked). I've found this forum-tutorial that does refer to the problem as most vexing parse, but it's solution (put parenthesis around argument) doesn't solve the problem (it's a long bunch of error msgs in that case, but I can edit it in the question later if it helps - those are all related to inheriting a virtual function).
I've tested my code if I use the constructor with all the parameters on default, and even if I just construct the first parameter separately:
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
I can use the code as it is, but it would be greatly appreciated if somebody could give me a more elegant solution to the one I'm using right now.
EDIT: error msgs I get when I fix the most vexing parse
If I use the code with parenthesis:
algoContainer myAC((algo1Concrete(workData)));
My errors are:
/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&’
I renamed the paths and inserted the example file and class names (the same as above) for readability. Just a remark: line 45
is the definition of the constructor in question. On the other hand, line 36
is the line class algoContainer
.
I also tried with this code:
algoContainer myDect((algo1Virtual)(algo1Concrete(workData)));
And then the errors are completely different:
/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&’
Hope this helps.
algoContainer myAC((algo1Concrete(workData)));
with the disambiguating parenthesis? – Atroposstd::move
and it was what I was looking for... Unfortunately, I can't use it because the group library is still not using C++11. If you could type up what you just said in you last command nicely as an answer, I'll accept it. – Nertie