Есть ли способ объявить сразу несколько объектов одного типа и сразу же инициализировать их одним и тем же значением только одним выражением? - PullRequest
6 голосов
/ 08 февраля 2020

Я хочу объявить несколько объектов одного типа и инициализировать их одним и тем же значением только одним выражением; без необходимости объявлять и инициализировать их отдельными операторами.

То, что я хочу, это что-то вроде:

int a = b = 10;  // dummy-statement. This does not work.

или

int a = int b = 10; // dummy-statement. This does not work either.

вместо

int b = 10;
int a = b;

Есть ли способ сделать это?

Ответы [ 4 ]

4 голосов
/ 08 февраля 2020

Технически вы можете инициализировать несколько переменных, используя структурированное связывание, доступное в C ++ 17, но это явно извращение: онлайн-компилятор

#include <cstddef>
#include <type_traits>
#include <tuple>
#include <utility>

// tuple-like type
template
<
    ::std::size_t x_count
,   typename x_Value
> class
t_Pack
{
    private: x_Value && m_value;

    public: constexpr t_Pack(x_Value && value): m_value{::std::move(value)}
    {}

    public: template
    <
        ::std::size_t x_index
    > constexpr auto
    get(void) noexcept -> x_Value &&
    {
        return ::std::move(m_value);
    }
};

// specializations to make structured bindings work
namespace std
{
    template
    <
        ::std::size_t x_count
    ,   typename x_Value
    > struct
    tuple_size<::t_Pack<x_count, x_Value>>
    :   public ::std::integral_constant<::std::size_t, x_count> 
    {};


    template
    <
        ::std::size_t x_index
    ,   ::std::size_t x_count
    ,   typename x_Value
    > struct
    tuple_element<x_index, ::t_Pack<x_count, x_Value>>
    {
        public: using type = x_Value;
    };
}

// helper
template
<
    ::std::size_t x_count
,   typename x_Value
> constexpr auto
pack(x_Value && value)
{
    return t_Pack<x_count, x_Value>{::std::move(value)};
}
auto [a, b, c, d, e] = pack<5>(10);
4 голосов
/ 08 февраля 2020

Я думаю, вы хотите это:

int b=10, a=b;
4 голосов
/ 08 февраля 2020

Технически, да: int a = value, b = a;, или вы можете рассмотреть int a, b = a = value;. Без повторяющихся идентификаторов, нет, по крайней мере, не в C; грамматика просто не предусматривает этого. Каждый ” декларатор = инициализатор ” в грамматике может объявить только один объект на производство грамматики в C 2018 6.7.6 1 и явный оператор в 6.7.6 2: «Каждый декларатор объявляет один идентификатор…»

Как уже упоминалось в комментарии, это ужасный способ сделать это в C ++. Я не делаю никаких заявлений относительно правил C ++ относительно порядка инициализации в одном объявлении, вопросов о многопоточности и так далее. Это представлено только в качестве учебного упражнения. Никогда не используйте это в производственном коде.

template<class T> class Sticky
{
private:
    static T LastInitializer;   //  To remember last explicit initializer.
    T Value;                    //  Actual value of this object.

public:
    //  Construct from explicit initializer.
    Sticky<T>(T InitialValue) : Value(InitialValue)
        { LastInitializer = InitialValue; }

    //  Construct without initializer.
    Sticky<T>() : Value(LastInitializer) {}

    //  Act as a T by returning const and non-const references to the value.
    operator const T &() const { return this->Value; }
    operator T &() { return this->Value; }
};

template<class T> T Sticky<T>::LastInitializer;

#include <iostream>

int main(void)
{
    Sticky<int> a = 3, b, c = 15, d;

    std::cout << "a = " << a << ".\n";
    std::cout << "b = " << b << ".\n";
    std::cout << "c = " << c << ".\n";
    std::cout << "d = " << d << ".\n";
    b = 4;
    std::cout << "b = " << b << ".\n";
    std::cout << "a = " << a << ".\n";
}

Вывод:

a = 3.
b = 3.
c = 15.
d = 15.
b = 4.
a = 3.
2 голосов
/ 08 февраля 2020

не может выполнить инициализацию.
может выполнить назначение.

int a, b;
a = b = 10;
...