我的结构定义如下:
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.
}
这样做不正常,因为A(b)
尝试使用第二个构造函数(非常量引用是首选选项,第一个构造函数是常量引用),但是B
没有任何B(A&)
。
此外,我想为B添加move
构造函数:
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)...)
{}
};
现在,最后一步是融合前两个构造函数:
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)...)
{}
};
问题:如果第一个版本导致冲突,最后一个版本(我的最终目的)明确表示它也不起作用。我怎么能实现这个目标呢?
答案 0 :(得分:2)
如果参数类型b
可转换为B
,则可能的解决方案是使用std::enable_if
和std::is_convertible
仅包含第一个构造函数:
template <
class fw_B,
class = typename std::enable_if<std::is_convertible<fw_B, B>::value, T>::type>
A(fw_B&& b)
例如:
#include <iostream>
#include <type_traits>
struct B
{
B() {}
B(int) {}
};
struct C {};
struct A : B, C
{
template <
class T,
class = typename std::enable_if<std::is_convertible<T, B>::value, T>::type>
A(T&& t) { std::cout << "A(T&&)\n"; }
template <class... TArgs>
A(TArgs&&... targs) { std::cout << "A(TArgs&&)\n"; }
};
int main()
{
B b;
A a1(b);
A a2(4);
A a3("hello");
return 0;
}
输出:
A(T&&) A(T&&) A(TArgs&&)
请参阅http://ideone.com/xJEjic上的演示。