繁体   English   中英

赋值运算符

[英]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) {}
};

如果ABC之间存在关系,请明确说明。 现在您可以使用单个值来初始化它们:

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;

话虽如此...


C++17 !!!

我们有 结构化绑定,所以耶!!!

auto [a, b, c] = {10, 10, 10};

哦,你不能这样做吗? 那好吧...


C++17

auto [a, b, c] = std::tuple{10, 10, 10};

C++20 !!!

我们有指定的初始化器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之前声明BC 所以:

int C, B, A = B = C = 10;

这是完全合法且定义明确的代码。 但我并不是说这是你应该做的。 (欢迎发表评论,举例说明这种表格可能有用的地方!)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM