sim*_*mon 6 c++ type-traits c++11
是否可以编写一个特征,这会产生它所使用的类的类型?如何在下面的例子中实现get_class?
class Foo {
typedef get_class::type type; // type = Foo now
};
Run Code Online (Sandbox Code Playgroud)
注意:我必须编写一个宏,它在类体中扩展,用于多个类,所以我不能简单地写'typedef Foo type;'
使用案例:
我有一个可反射的(...)宏,它生成基础设施来迭代成员,访问它们并使用它们的名称查找它们:
class Foo
{
friend std::ostream &operator<<(std::ostream &, const Foo&);
reflectable(
(int) bar,
(double) baz
)
}
Run Code Online (Sandbox Code Playgroud)
reflectable(...)应该是一个宏,所以我可以将类型和成员名称分别作为字符串来为查找构建映射.
我希望所有可反射的类都是可流式的,但如果我将reflectable()宏放到私有部分,我必须将友元声明添加到类中.我想将它移动到宏:
friend std::ostream &operator<<(std::ostream &, const get_class::type&);
Run Code Online (Sandbox Code Playgroud)
抱歉,但我很确定在标准 C++ 中,您无法以某种方式将类名传递给宏。对于一些失败的尝试,请参阅此答案的末尾。
也就是说,我认为最好的选择是稍微改变你的设计。代替
friend std::ostream &operator<<(std::ostream &, const get_class::type&);
Run Code Online (Sandbox Code Playgroud)
提供公共成员函数
void stream_to (std::ostream &) const {
// Implementation
}
Run Code Online (Sandbox Code Playgroud)
以及免费的功能模板
template<typename T, typename std:: enable_if<has_stream_to<T>::value>::type * = nullptr>
std::ostream &operator<<(std::ostream & s, T const & t) {
t.stream_to(s);
return s;
}
Run Code Online (Sandbox Code Playgroud)
在您的库/程序命名空间中。(注意:稍后我将添加该特征has_stream_to,以便在 C++ 标记中不耐烦地搜索“检测成员函数”)
无效的方法:
使用指向成员函数的指针,使用模板函数提取类类型。原因:&foo具有成员函数的类内部foo不会给出指向 的成员函数指针foo。语法(按照标准)要求&C::foo是(C类名在哪里......)。
使用指向数据成员的指针,通过模板函数提取类类型。理由和上面一样。
使用返回的专用成员函数*this,推断返回类型以获得类类型。原因:需要一个实例来调用此函数。
使用指向静态成员函数的指针。原因:此类指针与指向自由函数的指针相同,无法从中推断出类名。
this在成员初始化中使用指针。原因:成员类型需要以某种方式对类类型进行编码,但auto对于非静态数据成员是不允许的。