Is there a way to declare multiple objects of the same type at once and initialize them immediately with the same rvalue by just one expression?
Technically, yes: int a = value, b = a;
, or you might consider int a, b = a = value;
. Without repeating identifiers, no, at least not in C; the grammar simply does not provide for it. Each ”declarator =
initializer” in the grammar can declare only one object, per grammar production in C 2018 6.7.6 1 and explicit statement in 6.7.6 2: “Each declarator declares one identifier…”
As mentioned in a comment, here is a horrible way to do it in C++. I make no representations regarding C++’s rules about order of initialization in a single declaration, issues about threading, and so on. This is presented as an educational exercise only. Never use this in production code.
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";
}
Output:
a = 3. b = 3. c = 15. d = 15. b = 4. a = 3.
I think you want this:
int b=10, a=b;
Technically you can initialize several variables using structured binding available in C++17, but this is clearly a perversion: online compiler
#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);