C++ Weekly - Episode 141 脱水版: Designated Initializers And Lambdas

33 阅读1分钟

C++ Weekly - Episode 141 脱水版: Designated Initializers And Lambdas

指定初始化和 lambda

C++11 引入了指定初始化, 例如对于一下结构体, 我们可以这样初始化:

struct S
{
    unsigned int i;
    int j;
};

S s { .i = 1, .j = 2};

这种初始化方式和大括号初始化有点类似, 会检查参数类型, 避免发生隐式转换, 比如:

S s { .i = -1, .j = 2};

编译器将产生编译错误:

error: constant expression evaluates to -1 which cannot be narrowed to type 'unsigned int' [-Wc++11-narrowing]

回到主题, 试试用 lambda. 通过立刻调用的 lambda 也可以用于指定初始化.

struct S
{
    unsigned int i;
    int j;
};

auto value = S {
    .i = [](){ return 1; }(),
    .j = 2 };

假如是一个模板类, 是否能通过指定初始化?

template<typename T>
struct S
{
    T i;
    int j;
};

auto value = S {
    .i = [](){ return 1; }(),
    .j = 2 };

无法编译, 编译器报错:

error: no viable constructor or deduction guide for deduction of template arguments of 'S'

所以模板类, 我们需要一个构造函数来初始化:

template<typename T>
struct S
{
    S(T i_, int j_) : i(i_), j(j_) { }
    T i;
    int j;
};

auto value = S {
    [](){ return 1; }(),
    2 };

构造函数传入 lambda 调用作为参数也可以, 但是不能指定初始.