标签: list-initialization

由列表初始化初始化的函数参数的默认值

任何人都可以帮助我解决以下问题吗?

有一个简单的代码:

#include <vector>

struct A {
    std::vector<int> vec;
};

void func (A &&a = {}) {}

int main()
{
    func();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我尝试通过gcc 5.4.0编译它时,我收到错误:

undefined reference to `std::vector<int, std::allocator<int> >::vector()'
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,但clang编译得很好.此外,如果稍微修改代码,它编译没有任何问题:

#include <vector>

struct A {
    std::vector<int> vec;
};

void func (A &&a) {}

int main()
{
    func({});
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我真的不明白第一个代码有什么问题.

c++ aggregate-initialization c++11 list-initialization

19
推荐指数
1
解决办法
518
查看次数

为什么自动初始值设定项的自动和模板类型推导会有所不同?

我理解,给定一个支撑的初始化程序,auto将推导出一种类型std::initializer_list,而模板类型推导将失败:

auto var = { 1, 2, 3 };   // type deduced as std::initializer_list<int>

template<class T> void f(T parameter);

f({ 1, 2, 3 });          // doesn't compile; type deduction fails
Run Code Online (Sandbox Code Playgroud)

我甚至知道在C++ 11标准中指定的位置:14.8.2.5/5 bullet 5:

[如果程序有,则这是一个非推导的上下文]一个函数参数,其关联参数是初始化列表(8.5.4),但参数没有std :: initializer_list或者可能是cv-qualified std :: initializer_list的引用类型.[ 例如:

模板void g(T);

克({1,2,3}); //错误:没有推断T的参数

- 结束例子 ]

我不知道或不理解的是为什么存在这种类型演绎行为的差异.C++ 14 CD中的规范与C++ 11中的规范相同,因此标准化委员会可能不会将C++ 11行为视为缺陷.

有人知道为什么auto推导出支撑初始值设定项的类型,但是不允许使用模板吗?虽然对"这可能是原因"形式的推测性解释很有意思,但我对那些知道为什么标准是按原样编写的人的解释特别感兴趣.

c++ templates c++11 list-initialization template-argument-deduction

18
推荐指数
2
解决办法
1016
查看次数

调用C++ Copy构造函数而不是initializer_list <>

基于此代码

struct Foo 
{
   Foo() 
   {
       cout << "default ctor" << endl;
   }

   Foo(std::initializer_list<Foo> ilist) 
   {
       cout << "initializer list" << endl;
   }

   Foo(const Foo& copy)
   {
       cout << "copy ctor" << endl;
   }
};

int main()
{

   Foo a;
   Foo b(a); 

   // This calls the copy constructor again! 
   //Shouldn't this call the initializer_list constructor?
   Foo c{b}; 



   _getch();
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

默认ctor

复制ctor

复制ctor

在第三种情况下,我将b放入大括号初始化,它应该调用initializer_list <>构造函数.

相反,复制构造函数起带头作用.

你们有人会告诉我这是如何运作的,为什么?

c++ copy-constructor initializer-list list-initialization

18
推荐指数
2
解决办法
723
查看次数

return {}和return Object {}之间的区别

这两个功能之间有什么显着差异吗?

struct Object {
    Object(int i) : i{i}
    {
    }

    int i;
};

Object f() { return {1}; }
Object g() { return Object{1}; }
Run Code Online (Sandbox Code Playgroud)

c++ initialization c++11 list-initialization

18
推荐指数
2
解决办法
1078
查看次数

为什么仅在列表初始化的情况下才会出现缩小转换警告?

我有以下代码:

class A
{
    public:
        A(const unsigned int val) : value(val) {}

        unsigned int value;
};

int main()
{
    int val = 42;
    A a(val);
    A b{val};       // <--- Warning in GCC, error in Microsoft Visual Studio 2015

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么仅在列表初始化使用的情况下才会出现缩小转换警告?

c++ initialization narrowing c++11 list-initialization

16
推荐指数
2
解决办法
864
查看次数

GCC拒绝列表初始化参数

我有以下代码:

#include <initializer_list>
#include <utility>

enum class Classification
{
  Unspecified,
  Primary,
  Secondary
};

class ClassificationMap
{
public:
  ClassificationMap(std::initializer_list<std::pair<const Classification, int>> content = {});
};

void foo(ClassificationMap) {}

int main()
{
    foo({{Classification::Unspecified, 42}});
}
Run Code Online (Sandbox Code Playgroud)

Visual Studio 2013和2017以及Clang 3.4.1(及以上版本)都编译好了代码.从我的POV来看,它也应该没问题.但是,GCC 5.1拒绝编译它,并出现以下错误:

<source>: In function 'int main()':
<source>:22:44: error: could not convert '{{Unspecified, 42}}' from '<brace-enclosed initializer list>' to 'ClassificationMap'
     foo({{Classification::Unspecified, 42}});
Run Code Online (Sandbox Code Playgroud)

[实例]

(我将正确的标准flag(-std=c++11)传递给GCC和Clang).

我的代码中是否存在问题,或者这实际上是GCC错误?


补充信息:在我的实际代码中,初始化列表用于初始化类的无序映射成员ClassificationMap(这就是它的类型就是它的原因).我需要代码在VS2013和GCC 5.1中工作

c++ gcc initializer-list c++11 list-initialization

16
推荐指数
1
解决办法
653
查看次数

初始化变量时使用大括号({})或等号(=)

当我阅读《C++编程语言第4版》时,要初始化变量,作者说最好使用{}而不是=初始化变量:

变量初始化

但我发现使用的人={}.
那么哪种方法是值得坚持的好原则呢?=或者{}

c++ initialization list-initialization

16
推荐指数
1
解决办法
2万
查看次数

为什么Foo({})调用Foo(0)而不是Foo()?

由代码中的clang 3.5.0和gcc 4.9.1生成的可执行文件

#include <iostream>

struct Foo
{
   Foo() { std::cout << "Foo()" << std::endl; }
   Foo(int x) { std::cout << "Foo(int = " << x << ")" << std::endl; }
   Foo(int x, int y) { std::cout << "Foo(int = " << x << ", int = " << y << ")" << std::endl; }
};

int main()                 // Output
{                          // ---------------------
   auto a = Foo();         // Foo()
   auto b = Foo(1);        // Foo(int = 1)
   auto c = …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer value-initialization list-initialization c++14

15
推荐指数
1
解决办法
1164
查看次数

传递大括号列表参数时调用可变参数函数模板的问题

考虑这个功能模板:

template <class... T>
void foo (std::tuple<T, char, double> ... x);
Run Code Online (Sandbox Code Playgroud)

此调用有效:

using K = std::tuple<int, char, double>;
foo ( K{1,'2',3.0}, K{4,'5',6.0}, K{7,'8',9.0} );
Run Code Online (Sandbox Code Playgroud)

这个没有:

foo ( {1,'2',3.0}, {4,'5',6.0}, {7,'8',9.0} );
Run Code Online (Sandbox Code Playgroud)

(gcc和clang都抱怨过多论据foo)

为什么第二次调用有问题?我可以重写声明,foo以便第二次通话也被接受吗?

模板参数T仅用于实现可变参数.实际类型是已知和固定的,只有参数的数量不同.在现实生活中,类型不同int, char, double,这只是一个例子.

我不能使用C++ 17.更喜欢C++ 11兼容的解决方案.

c++ variadic-templates c++11 list-initialization

15
推荐指数
1
解决办法
544
查看次数

您可以使用花括号初始化列表作为(默认)模板参数吗?

我需要定义一个接受多个 3D 坐标作为参数的 C++ 模板。当这些坐标的所有维度都定义为单独的整数变量时,参数列表将变得非常长 - 3 个坐标需要 9 个参数,这使得模板难以使用。

因此,非常希望以使用编译时数组的方式声明模板。它们的默认参数也应该直接在模板声明的位置声明为值,而不是变量名。

经过一些实验,令我惊讶的是,我发现 GCC 13 将接受以下 C++ 程序std=c++20

#include <cstdio>
#include <array>

template <
    std::array<int, 3> offset = {0, 0, 0}
>
struct Array
{
    void operator() (int i, int j, int k) 
    {
        printf("(%d, %d, %d)\n", i + offset[0], j + offset[1], k + offset[2]);
    }
};

int main(void)
{
    Array arr_default;
    arr_default(0, 0, 0);

    Array<{1, 1, 1}> arr;
    arr(0, 0, 0);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然而,clang 18 拒绝使用 …

c++ language-lawyer list-initialization braced-init-list c++-templates

15
推荐指数
1
解决办法
660
查看次数