【问题标题】:C++ pass *this to base constructorC++ 将 *this 传递给基本构造函数
【发布时间】:2017-10-11 18:15:11
【问题描述】:

将 *this 传递给基类构造函数是否有效?

template<class Lambda>
struct EmptyL : Lambda
{
    EmptyL() : Lambda(*this) //<- is this valid c++?
    { }
};

int main () {    
auto l = []() { return 34; };
auto a = EmptyL<decltype(l)>();
return a();
}

EDIT1:

  • 我为什么要这样做?因为 lambda 表达式生成的 ClosureType 不是默认可构造的。通过这个“技巧”,我可以默认构造这样的 ClosureType。
  • 此外,模板参数Lambda 的要求是,它必须为空 => static_assert(std::is_empty_v&lt;Lambda&gt;)

【问题讨论】:

  • 您为什么需要这样做?你的基类已经有它的this
  • 语法有效但没有意义,为什么要从未初始化的结构中复制?
  • 注意*this 还没有被初始化。很难想象这会有用或做你想做的事情。
  • 这是一个可怕的问题。当然,从技术上讲,是的,将*this 传递给基类构造函数是可以的,但这甚至不会使您的示例变得正常,并且将“是”作为实际答案发布会误导性地积极有害。这就像用unsigned f() { unsigned u1, u2; return u1 + u2; } 的例子询问“可以添加两个无符号整数吗”。
  • 这里有可能提出一个好问题,但你的例子有缺陷。你真正想做什么?

标签: c++ c++11


【解决方案1】:

这是有效的并且非常有用:您的基类可能有一个模板 ctor,然后它将知道后代的类型。

struct Lambda {
    template<typename Desc>
    Lambda(const Desc&)
        : myType(Desc::myType)  // static in Desc
        , arity(Desc::arity) {} // static in Desc
    Type myType;
    const size_t arity;
};

此时,我们有没有虚拟表的运行时类型枚举,我们可以为成员提取任意数量的类型相关参数,如果再添​​加一个,则无需更改所有后代中的所有 ctor 调用 (这对于虚拟基类来说尤其痛苦),或者更糟糕的是,拥有虚拟 fns cor 这些。您只需在任何地方传递this - 它甚至对宏友好:)。

是的,您可以通过传递除此之外的其他内容来规避它。不,这不是一个安全功能——它是一个便利功能。这与 CRTP 非常相似,但基础不是模板,因为它不需要整个类中的编译时后代类型,只需要在(模板)ctor 内部。

【讨论】:

  • 我会说他的示例调用了未定义的行为,特别是如果 lambda 具有状态。
  • 您能详细说明原因吗?在 Desc 中,我假设 myType 和 arity 是 static constexpr const 如果这具有误导性......
  • @lorro :非常感谢您的分析!您是否有来自标准的报价来验证它是否有效?
  • @Kilian :我不希望您会发现标准的任何特定部分明确说明这一点。只是模板类可以在任何地方使用作为模板参数类型的指针 - Lambda 就是在此时定义的。
猜你喜欢
  • 1970-01-01
  • 2019-01-06
  • 1970-01-01
  • 2014-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
相关资源
最近更新 更多