decltype(*this)等效的外部函数体

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)

Dan*_*our 2

抱歉,但我很确定在标准 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对于非静态数据成员是不允许的。

  • 我没有投反对票,但请注意,您的“stream_to”仍然必须公开才能进行检测。此外,“final”在非虚拟成员函数上的格式不正确。 (2认同)