I have a struct defined as follows:
struct A : public B, public C
{
A(const B& b) : B(b), C()
{}
template<typename... Args>
A(Args&&... args) : B(), C(std::forward<Args>(args)...)
{}
};
int main()
{
B b;
A sample1(b);
A sample2(3); // For example, B has a B(int) constructor.
}
And this doesn’t work fine, because, A(b) tries use the second constructor (the non-constant reference is the preferred option, and the first constructor is a constant reference), but B hasn’t any B(A&).
And moreover, I want to add a move constructor for B:
struct A : public B, public C
{
A(const B& b) : B(b), C()
{}
A(B&& b) : B(std::move(b)), C()
{}
template<typename... Args>
A(Args&&... args) : B(), C(std::forward<Args>(args)...)
{}
};
Now, the last step is to fusion the first two constructors:
struct A : public B, public C
{
template<typename fw_B>
A(fw_B&& b) : B(std::forward<fw_B>(b)), C()
{}
template<typename... Args>
A(Args&&... args) : B(), C(std::forward<Args>(args)...)
{}
};
Question: if the first version causes collision, the last version (my final purpose) its clear that it doesn’t work also. How could I achieve this goal?
A possible solution would be use
std::enable_ifwithstd::is_convertibleto only include the first constructor if the type of argumentbis convertible toB:For example:
Output:
See demo at http://ideone.com/xJEjic .