我试图模仿可继承构造函数的行为,因为它们还没有用g ++实现。
我尝试了这里描述的技术https://stackoverflow.com/a/5411992/234261,但是当我想添加自己的构造函数时,我遇到了问题。具体来说,我试图添加一个专门的复制构造函数,以及继承所有其他构造函数。不幸的是,总是调用继承的,更通用的复制构造函数。
#include <iostream>
struct A {
A(){}
A(const A &){ std::cout << "IN A" << std::endl; }
};
struct B : public A{
template<typename ...Args,
typename = typename std::enable_if
<
std::is_constructible<A, Args...>::value
>::type>
B(Args &&...args)
: A(std::forward<Args>(args)...) {}
// These don't work either.
//B(const A &a):A(a){ std::cout << "IN B-A" << std::endl; }
//B(const B &b):A(b){ std::cout << "IN B-B" << std::endl; }
};
template<>
B::B(const A &a):A(a){ std::cout << "IN B-A" << std::endl; }
template<>
B::B(const B &b):A(b){ std::cout << "IN B-B" << std::endl; }
int main(){
A a; // 1. Prints nothing as expected
B b(a); // 2. Prints "IN A" only
B b1(b); // 3. Prints "IN A" only
return 0;
}
我希望[3]打印 IN A 然后 IN B-B 。不知何故,我设法让[2]在我的实际代码中工作,但由于某种原因不能在这个小例子中重复它。
我知道正在创建模板构造函数是因为子类(B)实际上可以用于构造超类(A)。
但是,为什么我的显式专业化不会被调用?我的专业不正确吗?还有更好的方法吗?
如果有人想要运行此示例,请链接到此示例http://ideone.com/eUHD5
我正在使用gcc 4.6
答案 0 :(得分:4)
以下“有效”:
struct B : public A
{
template<typename ...Args, typename = typename std::enable_if<std::is_constructible<A, Args...>::value>::type>
B(Args &&...args) : A(std::forward<Args>(args)...) {}
B(const A & a) : A(a){ std::cout << "IN B-A" << std::endl; }
B(const B & b) : A(b){ std::cout << "IN B-B" << std::endl; }
};
int main()
{
A a;
B b(a);
B b1(static_cast<B const &>(b));
}
这是旧的模板 - 过载 - 是一个更好的匹配板栗。有关详细深入的说明,请参阅STL's lecture #3。基本上,将b
绑定到推断模板参数Args... = { B }
的引用完全匹配身份,同时将其绑定到B const &
需要限定符转换,这是身份转换的严格超集
通过显式转换为const-reference,模板化和非模板构造函数现在都是完美的匹配,但是作为非模板是关系。
答案 1 :(得分:2)
这将无需将内容转换为const:
#include <iostream>
struct A {
A(){}
A(const A &){ std::cout << "IN A" << std::endl; }
};
struct B : public A{
B() = default;
template<typename A0, typename ...Args,
typename = typename std::enable_if
<
!std::is_same<typename std::decay<A0>::type, A>::value &&
!std::is_same<typename std::decay<A0>::type, B>::value &&
std::is_constructible<A, A0, Args...>::value
>::type>
B(A0&& a0, Args &&...args)
: A(std::forward<A0>(a0), std::forward<Args>(args)...) {}
B(const A &a):A(a){ std::cout << "IN B-A" << std::endl; }
B(const B &b):A(b){ std::cout << "IN B-B" << std::endl; }
};
int main(){
A a; // 1. Prints nothing as expected
B b(a); // 2. Prints "IN A" only
B b1(b); // 3. Prints "IN A" only
return 0;
}
虽然作者比较麻烦,但对客户来说更清洁。