[英]Assignment operators
以下表达式在 C++ 中有效:
A = B = C = 10;
变量 A、B 和 C 现在将包含值 10。
我试图弄清楚如何使它,以便 A、B 和 C 在声明时可以包含 10 的值,而不是稍后分配它们;
#include <iostream>
using namespace std;
int main()
{
int A, B, C, = 10;
int result;
result = A = B = C = 10;
cout << A << B << C << 10;
result 0;
}
在 C++ 中,每个变量定义都必须有自己的初始化程序。 如果你想链接它,那么你需要使用类似的东西
int A = 10, B = A, C = B;
这将满足您的需求,但您需要手动指定初始化程序。
你不能直接做你想做的事。 但是,在我看来,想要用相同的值初始化它们足以定义 class:
struct ABC {
int A,B,C;
ABC(int x) : A(x),B(x),C(x) {}
};
如果A
、 B
和C
之间存在关系,请明确说明。 现在您可以使用单个值来初始化它们:
ABC abc{10};
你当然可以写: int a = 10, b = 10, c = 10;
声明与赋值有很大不同。 通常赋值运算符返回对 object 的引用。 例如这个操作的类型是int&
:
int a;
a = 10;
这允许您像这样链接分配: a = b = c = 10
:在一天结束时,该运算符的类型再次为int&
,您仍然可以在右侧再添加一个分配。
变量的定义是另一回事。 每个变量都必须获得它自己的值(或根本没有值),但是没有办法“在一个赋值中”“分配”(实际上初始化)单个值。
但是,也许这可以解决您的实际问题:
const int value = 10;
int a = value, b = value, c = value;
顺便说一句,在一行中定义多个变量是一种不好的做法。 您的示例是该问题的一个例证。 其他问题:在下一个示例中,指针是什么,引用是什么,以及什么只是纯 int?
int val;
int* a, b;
int& c = val, d = val;
我推荐普遍理解和使用的: int a = 10, b = 10, c = 10;
话虽如此...
我们有 结构化绑定,所以耶!!!
auto [a, b, c] = {10, 10, 10};
哦,你不能这样做吗? 那好吧...
C++17
auto [a, b, c] = std::tuple{10, 10, 10};
我们有指定的初始化器Yeey!!
auto [a, b, c] = std::tuple{[0... 2] = 10};
auto [a, b, c] = (int[]){[0... 2] = 10};
哦,你不能这样做吗? 那好吧...
好的...让我们手动完成。 是吗? :(
auto test()
{
auto [a, b, c] = make_repeating_tuple<3, 10>();
// or, alternative
auto [a, b, c] = make_repeating_tuple<3>(10);
}
执行
#include <tuple>
#include <utility>
#include <type_traits>
namespace details
{
template <auto Val, std::size_t... Is>
constexpr auto make_repeating_tuple_impl(std::index_sequence<Is...>)
{
// black magic
return std::tuple{[] (auto) { return Val; }(Is)...};
}
}
template <int N, auto Val>
constexpr auto make_repeating_tuple()
{
return details::make_repeating_tuple_impl<Val>(std::make_index_sequence<N>{});
}
实施(替代)
namespace details
{
template <class T, std::size_t... Is>
constexpr auto make_repeating_tuple_impl(T val, std::index_sequence<Is...>)
{
static_assert(std::is_trivially_copy_constructible_v<decltype(Val)>); // because
// black magic
return std::tuple{[=] (auto) { return val; }(Is)...};
}
}
template <int N, class T>
constexpr auto make_repeating_tuple(T val)
{
return details::make_repeating_tuple_impl(val, std::make_index_sequence<N>{});
}
auto test()
{
DECL_CHAIN_ASSIGN(10, a, b, c);
}
执行:
// the darkest of magics
#define DECL_CHAIN_ASSIGN(val, ...) \
auto [__VA_ARGS__] = make_repeating_tuple<PP_NARG(__VA_ARGS__)>(val)
和
#define PP_NARG(...) \
PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) \
PP_ARG_N(__VA_ARGS__)
#define PP_ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,N,...) N
#define PP_RSEQ_N() \
63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
// taken from
// https://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments
更严肃的一点是:不要使用宏!
C++ 不能那样工作。 虽然你可以在一个语句中声明多个相同类型的变量,但你不能用一个值来初始化它们,它们必须单独初始化,例如
int A = 10, B = 10, C = 10;
因此,您尝试做的仅适用于分配,而不适用于声明。
如果你真的想保持你的A = B = C = 10;
语法,那么您实际上可以在单行声明/初始化程序中执行此操作,前提是您在A
之前声明B
和C
。 所以:
int C, B, A = B = C = 10;
这是完全合法且定义明确的代码。 但我并不是说这是你应该做的。 (欢迎发表评论,举例说明这种表格可能有用的地方!)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.