c++ - 可变参数模板和 std::array 意外行为

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

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

#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

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

最佳答案

构造函数中的语句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

关于c++ - 可变参数模板和 std::array 意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60753894/

相关文章:

wpf - WPF 中的复选框模板

c++ - QHash 问题

c++ - 关于数组的边界

c++ - 在 lambda 中移动捕获

templates - C++ 中类似 Haskell 的 `const`

c++ - 基于策略的设计C++问题

c++ - 候选人期望 6 个参数,提供 0 个

c++ - 我如何链接我的 C++ 控制台应用程序以控制现有控制台?

c++ - 是否可以使用 operator new 和 initialiser 语法初始化非 POD 数组?

c++ - 从 C++ 中定义的异常返回整数