【发布时间】:2012-08-18 06:22:14
【问题描述】:
我正在试验 C++11 的新特性。在我的设置中,我真的很想使用继承构造函数,但不幸的是还没有编译器实现这些。因此,我试图模拟相同的行为。我可以这样写:
template <class T>
class Wrapper : public T {
public:
template <typename... As>
Wrapper(As && ... as) : T { std::forward<As>(as)... } { }
// ... nice additions to T ...
};
这很有效……大多数时候。有时使用Wrapper 类的代码必须使用SFINAE 来检测如何构造这样的Wrapper<T>。然而,存在以下问题:就重载决议而言,Wrapper<T> 的构造函数将接受任何参数——但如果类型为T 无法使用这些构造。
我试图使用enable_if 有条件地启用构造函数模板的不同实例化
template <typename... As, typename std::enable_if<std::is_constructible<T, As && ...>::value, int>::type = 0>
Wrapper(As && ... as) // ...
只要满足以下条件就可以正常工作:
-
T的适当构造函数是public -
T不是抽象的
我的问题是:如何摆脱上述两个约束?
我试图通过检查(使用 SFINAE 和 sizeof())表达式 new T(std::declval<As &&>()...) 是否格式良好 within Wrapper<T> 来克服第一个问题。但这当然行不通,因为派生类可以使用其基类的受保护构造函数的唯一方法是在成员初始化列表中。
对于第二个,我完全不知道——它是我需要的更多,因为有时它是实现T 的抽象函数的Wrapper,使其成为一个完整的类型。
我想要一个解决方案:
- 按照标准是正确的
- 适用于任何 gcc-4.6.*、gcc-4.7.* 或 clang-3.*
谢谢!
【问题讨论】:
-
我很着急,但也许 stackoverflow.com/questions/8984013/… 可以在这里提供帮助,但我不会指望 gcc 4.6 能做到这一点
-
这里的访问控制有点棘手:如果您使用
sizeof(),编译器将检查整个表达式,包括访问——但随后会从表达式的上下文中检查访问 ,在受保护的构造函数的情况下失败;除了sizeof之外的所有东西都只在重载解析和类型推断级别起作用,所以访问冲突不会触发 SFINAE——但是,我看不出用构造函数做某事,因为它不能作为模板参数传递.至于编译器支持,如果上面的 any 接受代码,我会很高兴。
标签: c++ templates c++11 template-meta-programming perfect-forwarding