标签: aggregate-initialization

为什么我可以从{}初始化常规数组,而不是std :: array

这有效:

int arr[10] = {};
Run Code Online (Sandbox Code Playgroud)

所有元素arr都被初始化为零.

为什么这不起作用:

std::array<int, 10> arr({}); 
Run Code Online (Sandbox Code Playgroud)

我从g ++(版本4.8.2)收到以下警告:

警告:缺少成员'std :: array <int,10ul> :: _ M_elems'的初始值设定项

c++ compiler-warnings aggregate-initialization c++11 g++4.8

10
推荐指数
2
解决办法
1443
查看次数

隐藏用于聚合初始化的空基类

考虑以下代码:

struct A
{
    // No data members
    //...
};

template<typename T, size_t N>
struct B : A
{
    T data[N];
}
Run Code Online (Sandbox Code Playgroud)

这就是你必须如何初始化 B:B<int, 3> b = { {}, {1, 2, 3} }; 我想避免基类不必要的空 {}。Jarod42 here提出了一个解决方案,但是,它不适用于元素默认初始化:B<int, 3> b = {1, 2, 3};很好,但B<int, 3> b = {1};不是:b.data[1]并且b.data[2]没有默认初始化为 0,并且会发生编译器错误。有什么方法(或者 C++20 会有)从构造中“隐藏”基类?

c++ initialization aggregate-initialization c++20

9
推荐指数
2
解决办法
445
查看次数

类似聚合的初始化,无需构造函数的多余调用

我主要尝试编写std::array. 但是,我对聚合初始化的规则(以及其他一些小细节)不太满意,因此不想使用它。

我不喜欢聚合初始化的事情:

  • 列表中少于必要的元素不会产生错误,这对于聚合的聚合来说尤其奇怪,例如
    struct A { int x,y; };
    std::array< A, 2 > arr{1,2,3};
    // produces A[0].x = 1, A[0].y = 2, A[1].x = 1, A[1].y = 0
    
    Run Code Online (Sandbox Code Playgroud)
  • 用户仍然可以调用私有/已删除的 ctor
    class B { B() = delete; };
    B{};  // no compile time error
    
    Run Code Online (Sandbox Code Playgroud)

到目前为止我所拥有的是以下内容:

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

template< typename T, typename ... Ts >
inline constexpr bool areT_v = std::conjunction_v< std::is_same<T, Ts> ... >;  

namespace ttt {
    template< typename T, int N >
    struct …
Run Code Online (Sandbox Code Playgroud)

c++ aggregate-initialization c++14

9
推荐指数
1
解决办法
345
查看次数

C++中的聚合初始化安全性

假设我有以下结构:

struct sampleData
{
       int x;
       int y;
};
Run Code Online (Sandbox Code Playgroud)

在使用时,我想将sampleData类型的变量初始化为已知状态.

sampleData sample = { 1, 2 } 
Run Code Online (Sandbox Code Playgroud)

后来,我决定我需要在我的sampleDatastruct中存储更多数据,如下所示:

struct sampleData
{
       int x;
       int y;
       int z;
};
Run Code Online (Sandbox Code Playgroud)

我的理解是,从我的预z数据结构遗留下来的两个字段初始化仍然是一个有效的语句,并将被编译.使用默认值填充缺少的字段.

这种理解是否正确?我最近一直在Ada工作,它也允许聚合初始化,但是它会将类似的问题标记为编译错误.假设我对上面的C++代码的假设是正确的,是否有一种语言结构可以将缺少的初始化值识别为错误?

c++ ada aggregate-initialization

8
推荐指数
1
解决办法
697
查看次数

原子结构的统一初始化?

struct S
{
    int x;
    int y;
};

std::atomic<S> asd{{1, 2}}; // what should this be? This doesn't work
Run Code Online (Sandbox Code Playgroud)

编辑:这两个{{1, 2}}({1, 2})在G ++,在铛没有工作的工作.clang有解决方法吗?

c++ atomic aggregate-initialization uniform-initialization c++11

8
推荐指数
1
解决办法
444
查看次数

空括号调用默认构造函数或构造函数采用std :: initializer_list吗?

以下是Effective Modern C++(第55页)的引用:

"假设你使用一组空的大括号来构造一个支持默认构造函数的对象,并且还支持std :: initializer_list构造.你的空括号是什么意思?等规则是你得到默认构造."

我用std :: array尝试过这个:

std::array<int, 10> arr{};
Run Code Online (Sandbox Code Playgroud)

并得到了g ++(版本4.8.2)的警告:

警告:缺少成员'std :: array <int,10ul> :: _ M_elems'的初始值设定项

这是在尝试std::array从空构造一个时得到的警告std::initializer_list(请参阅为什么我可以从{}初始化一个常规数组,而不是std :: array来讨论此警告).

那么,为什么上面的代码行不能解释为调用默认构造函数?

c++ aggregate-initialization c++11

8
推荐指数
1
解决办法
1113
查看次数

可以使用C++聚合初始化来构造实现接口的类的实例吗?

我希望有人可以给我一些技术细节,说明为什么以下内容无法编译,如果可能的话,还有一个解决方法.

我有一个名为Foo的现有结构,以及使用初始化列表创建Foo实例的代码.此代码编译和工作:

struct Foo {
    int id1;
    int id2;
};

int main()
{
    Foo f({1,2});

    return f.id1;
}
Run Code Online (Sandbox Code Playgroud)

我希望Foo能够实现一个接口:

struct Interface {
    // All pure virtual methods, but this won't compile even if empty
};

struct Foo : public Interface{
    int id1;
    int id2;
};

int main()
{
    Foo f({1,2});

    return f.id1;
}
Run Code Online (Sandbox Code Playgroud)

此代码不再编译,并且存在错误

cannot convert argument 1 from 'initializer list' to 'const _Ty &'
Run Code Online (Sandbox Code Playgroud)

(错误会根据您的确切编译器而改变.)

我发现有关聚合初始化的标准的这一部分:

[dcl.init.aggr]/1聚合是一个数组或类(第12条),1.1没有用户提供的,显式的或继承的构造函数(15.1),1.2没有私有或受保护的非静态数据成员(第14条) ),1.3没有虚函数(13.3),1.4没有虚拟,私有或受保护的基类(13.1).

虽然我不确定聚合初始化是否发生在这里.有人可以解释正在发生的错误,如果可能的话,可以提供我可以对界面进行的更改吗?我有几个需要这个接口的现有结构,以及许多使用这种形式的初始化的现有代码,我想尽可能少地重写它.谢谢!

c++ initializer-list aggregate-initialization

8
推荐指数
1
解决办法
454
查看次数

C++ 中聚合的带括号初始化的模板参数推导

在下面的代码中,使用模板参数推导来初始化A<T>对象,使用两种形式(根据大括号的类型不同):

template<typename T>
struct A{ T x; };

int main() {
    static_assert( A{1}.x == 1 ); //#1: ok in GCC and MSVC
    static_assert( A(1).x == 1 ); //#2: ok in GCC only
}
Run Code Online (Sandbox Code Playgroud)

第一种方式被 GCC 和 MSVC 接受,而第二种方式仅适用于 GCC,而 MSVC 打印错误:

error C2641: cannot deduce template arguments for 'A'
error C2780: 'A<T> A(void)': expects 0 arguments - 1 provided
error C2784: 'A<T> A(A<T>)': could not deduce template argument for 'A<T>' from 'int'
Run Code Online (Sandbox Code Playgroud)

演示: https: //gcc.godbolt.org/z/97G1acqPr

这是 MSVC 中的错误吗?

c++ language-lawyer aggregate-initialization c++20

8
推荐指数
1
解决办法
284
查看次数

我可以避免为std :: variant中的每个结构显式编写构造函数吗?

考虑以下代码:

#include <variant>

struct x {
  int y;
};

int main() {
  std::variant<x> v(std::in_place_type<x>, {3}); /*1*/
  return std::get<x>(v).y;
}
Run Code Online (Sandbox Code Playgroud)

即使聚合初始化,这也不会编译,也不会{}从行中删除/*1*/

x a{3};
x b({3});
Run Code Online (Sandbox Code Playgroud)

适用于"类似构造函数"的形式.我可以以某种方式使std::variant初始化器知道使用聚合初始化构造结构的可能性,而不必为我的实际案例中可能使用的每个结构编写无聊的样板构造函数吗?

我希望这可以工作,不知何故,根据cppreference,有问题的两个重载(5)和(6)都说

使用指定的替代T构造变量并使用参数[...] 初始化包含的值

如果重要的话,我正在使用GCC 7.

c++ variant aggregate-initialization c++17

7
推荐指数
1
解决办法
340
查看次数

在空基类中使用聚合初始化时如何避免{}

C ++ 17对基类的聚合初始化很棒,但是当基数仅用于提供某些功能(因此没有数据成员)时,它很冗长。

这是最小的示例:

#include <cstddef>
struct base_pod
{
    // functions like friend compare operator
};
template<typename T, std::size_t N>
struct der_pod : public base_pod
{
    T k[N];
};

int main()
{
    der_pod<int, 2> dp {{}, {3, 3} };
}
Run Code Online (Sandbox Code Playgroud)

如上面的示例所示,我必须提供empty {},否则将发生编译错误。现场演示。如果我忽略它:

prog.cc:15:28: error: initializer for aggregate with no elements requires explicit braces
        der_pod<int, 2> dp{3, 3};
                           ^
prog.cc:15:31: warning: suggest braces around initialization of subobject [-Wmissing-braces]
        der_pod<int, 2> dp{3, 3};
                              ^
                              {}
1 warning and 1 …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance aggregate-initialization

7
推荐指数
1
解决办法
128
查看次数