Variadi c шаблон и std :: array неожиданное поведение - PullRequest
2 голосов
/ 19 марта 2020

Я могу скомпилировать, но у меня проблемы с запуском следующего кода (я его свернул):

#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

Ясно, что первые две ячейки массив имеет мусорные номера после инициализации объекта. Я подозреваю, что каким-то образом повреждаю стек, но не могу понять, почему / где ...

1 Ответ

4 голосов
/ 19 марта 2020

Оператор Selector(args...); в конструкторе просто создает временный объект, который немедленно уничтожается; он ничего не делает для текущего объекта.

Я полагаю, вы хотите делегирующий конструктор (начиная с 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

...