【问题标题】:Variadic template and std::array unexpected behaviour可变参数模板和 std::array 意外行为
【发布时间】:2020-03-19 09:06:12
【问题描述】:

我可以编译,但运行以下代码时遇到问题(我已将其最小化):

#include <iostream>
#include <array>


template<int N>
class Selector {

public:

    template <typename... Args>
    Selector(int x, Args... args) noexcept {
        integers[sizeof...(Args)] = x;
        std::cout << "integers[" << sizeof...(Args) << "]=" << integers[sizeof...(Args)] << std::endl;  // OK

        Selector(args...);
    }

    Selector(int x) noexcept {
        integers[0] = x;
        std::cout << "integers[0]=" << integers[0] << std::endl;    // OK
    }


    void print_num(int i) const {
        std::cout << "integers[" << i << "]=" << integers[i] << std::endl;
    }

private:
    std::array<int, N> integers;
};

int main() {
    Selector<3> x(5, 10, 15);

    x.print_num(2); // OK
    x.print_num(1); // KO
    x.print_num(0); // KO

}

输出是:

integers[2]=5
integers[1]=10
integers[0]=15
integers[2]=5
integers[1]=1016039760
integers[0]=22034

很明显,数组的前两个单元格在对象初始化后具有垃圾编号。我怀疑我以某种方式破坏了堆栈,但我无法弄清楚为什么/在哪里......

【问题讨论】:

  • @WhozCraig 我没有索引 3,因为 sizeof...(Args)

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


【解决方案1】:

构造函数中的语句Selector(args...);,只是构造了一个立即销毁的临时对象;它与当前对象无关。

我想你想要delegating constructor(C++11 起):

template <typename... Args>
Selector(int x, Args... args) noexcept : Selector(args...) {
//                                     ^^^^^^^^^^^^^^^^^^^
    integers[sizeof...(Args)] = x;
    std::cout << "integers[" << sizeof...(Args) << "]=" << integers[sizeof...(Args)] << std::endl;  // OK
}

LIVE

【讨论】:

  • @RicoRico 你可能对 Java 感到困惑;这似乎能够做到这一点(我什至不确定)。
  • 这是我第一次在构造函数中使用可变参数模板,嗯……我用它就像我在函数调用中一样使用它呃……
  • @RicoRico 我明白了。是的Selector(args...); 会调用构造函数,但它与当前对象无关。
猜你喜欢
  • 2023-03-10
  • 2013-05-25
  • 2020-02-24
  • 2014-01-19
  • 1970-01-01
  • 1970-01-01
  • 2019-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多