【问题标题】:Initialization of variadic base classes可变参数基类的初始化
【发布时间】:2014-05-04 21:55:45
【问题描述】:

以下代码不起作用。它的目的是将参数传递给可变参数基类。这是否可能,如果可以,实现它的正确方法是什么? (Clang的报错信息是:an initializer for a delegating constructor must appear alone,看不懂。)

template<class... Visitors>
class Visited: public Visitors...
{
    public:
        template<class F>
        Visited(const F& f): F(f)               {}

        template<class F, class... Rest>
        Visited(const F& f, const Rest&... r):
            F(f), Visited(r...)                       {}
};

struct A {};
struct B {};
struct C {};

int main()
{
    A a;
    B b;
    C c;
    Visited<A,B,C> v(a, b, c);
}

【问题讨论】:

  • 错误只是说如果你委托给另一个构造函数,你不能初始化该列表中的任何其他内容。
  • 那么有没有办法做我想做的事,还是没有希望?
  • 应该可以吧,不过我没用过可变参数继承,所以不熟悉这种方法。

标签: c++ templates c++11 variadic


【解决方案1】:

这要容易得多,并且可以与 GCC 和 Clang(足够新的版本)一起使用:

template<class... Args>
Visited(const Args&... args) : Visitors(args)... {}

每个基类使用一个参数。如果您希望参数完美转发,请使用稍微不那么简洁的:

template<class... Args>
Visited(Args&&... args) : Visitors(std::forward<Args>(args))... {}

在这两种情况下,如果Visitors 只是一个类并且您希望避免意外转换,请考虑添加explicit

Live example

【讨论】:

  • 魔术,其实模板不是必须的。 Visited(const Visitors&amp;... args): Visitors(args)... {} 有效。谢谢!
  • @foxcub 这可能会引入额外的临时性,但如果这不是问题,那么是的,这是一个更简单的选择。
  • @foxcub 但是参数是Visitors,即你将它们“复制”到你的基础(很可能是隐式创建的Visitors)而不是用参数初始化基础。
  • 有趣。为什么这两种形式不同? IE。为什么你的模板版本避免复制,而我的没有?
  • 还有Visited(Visitors&amp;&amp;... args): Visitors(args)... {},或者类似的东西怎么样?这样可以避免复制吗?
猜你喜欢
  • 1970-01-01
  • 2021-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-19
相关资源
最近更新 更多