奇异重复模板模式与可变参数模板(C ++)

时间:2016-06-08 20:51:37

标签: c++ c++11 variadic-templates compile-time crtp

我有以下代码:

#include <iostream>

template <typename Derived>
struct Base {
    void print() const { static_cast<const Derived*>(this)->print(); }  
};

struct Value : public Base<Value> {
    int i;
    void print() const { std::cout << "Value: " << i << std::endl; }
    Value(int j) : i(j) {}
};

void do_variadic_thing() {}

template <typename Derived, typename... Args>
void do_variadic_thing(const Base<Derived>& b, Args... args) {
    std::cout << "Inside do_variadic_thing" << std::endl;
    b.print();
    do_variadic_thing(args...);
}

template <typename Derived>
void do_thing(const Base<Derived>& b) {
    std::cout << "Inside do_thing" << std::endl;
    b.print();
    do_variadic_thing(b, b, b);
}

int main(int argc, char** argv) {
    do_thing(Value(1));
}

此代码使用奇怪的重复模板模式使用名为print的方法定义编译时多态类。

我想要做的是从具有可变数量的参数(print)的函数运行do_variadic_thing方法。上面提供的代码编译,但产生一个奇怪的输出:

Inside do_thing
Value: 1
Inside do_variadic_thing
Value: 1
Inside do_variadic_thing
Value: 4206337
Inside do_variadic_thing
Value: 4206337

我不明白为什么在do_variadic_thing内第二次递归调用后打印的值会发生变化。参数b被复制3次;它的类型也是一样的(即Base<Value>)。似乎不知何故,在第二次调用之后,参数不再引用一些有效的内存。

这怎么可能?

3 个答案:

答案 0 :(得分:3)

通过引用传递:

void do_variadic_thing(const Base<Derived>& b, const Args&... args)
                                                         ^
                                                         here

答案 1 :(得分:1)

您正在按值传递第二个/第三个实例 - 考虑如何构建副本。

答案 2 :(得分:0)

变量b的类型是Base<Value> const&,但它引用的对象是Value类型。当您复制b以在do_thing内复制它时,您正在切片它;也就是说,只复制Base<Value>部分。