Нет, кроме variadic is_nothrow_constructible_v - PullRequest
1 голос
/ 10 апреля 2019

Какой из них правильный и почему?

Я думаю, что это первый, потому что Ts уже имеет && или const &, связанный с типом, но мне нравится быть уверенным, и на самом деле примеров такого конкретного случая noexcept не так уж много. .

template <typename T>
struct Test {
    T test;

    // A
    template <typename... Ts>
    Test(Ts &&... ts) noexcept(std::is_nothrow_constructible_v<T, Ts...>)
        : test(std::forward<Ts>(ts)...) {
    }

    // B
    template <typename... Ts>
    Test(Ts &&... ts) noexcept(std::is_nothrow_constructible_v<T, Ts &&...>)
        : test(std::forward<Ts>(ts)...) {
    }
};

1 Ответ

4 голосов
/ 10 апреля 2019

Я предпочитаю вариант C. Вы можете использовать оператор noexcept в спецификаторе noexcept и заставить его оценить вызов для вас.Я нахожу это намного проще для понимания, так как вы используете выражение, которое вы хотите сделать для спецификатора исключения.В вашем случае это выглядело бы как

template <typename T>
struct Test {
    T test;

    // C
    template <typename... Ts>
    Test(Ts &&... ts) noexcept(noexcept(T(std::forward<Ts>(ts)...)))
        : test(std::forward<Ts>(ts)...) {
    }
};

А теперь код говорит, что Test(Ts &&... ts) - это не исключение, если T(std::forward<Ts>(ts)...) - это не исключение.

...