标签: list-initialization

是否可以通过列表初始化来调用用户定义的转换函数?

这个程序合法吗?

struct X { X(const X &); };
struct Y { operator X() const; };

int main() {
  X{Y{}};   // ?? error
}
Run Code Online (Sandbox Code Playgroud)

n2672之后,经过缺陷978的修正,13.3.3.1 [over.best.ics]具有:

4 - 但是,当初始化列表只有一个元素并且转换为某个类X时,在考虑构造函数或用户定义的转换函数的参数时,它是13.3.1.7 [...]的候选者.或者引用(可能是cv-qualified)X被认为是X [...]的构造函数的第一个参数,只考虑标准转换序列和省略号转换序列.

这看起来很不正常; 它的结果是使用列表初始化强制转换指定转换是非法的:

void f(X);
f(Y{});     // OK
f(X{Y{}});  // ?? error
Run Code Online (Sandbox Code Playgroud)

据我所知n2640,列表初始化应该能够替换直接初始化和复制初始化的所有用法,但是似乎没有办法只使用list-initialization X从类型的对象构造一个类型的对象Y:

X x1(Y{});  // OK
X x2 = Y{}; // OK
X x3{Y{}};  // ?? error
Run Code Online (Sandbox Code Playgroud)

这是标准的实际意图吗?如果没有,它应该如何阅读或阅读?

c++ implicit-conversion c++11 list-initialization

6
推荐指数
2
解决办法
555
查看次数

实施定义的缩小转换?

C++ 11形式化了缩小转换的概念,并禁止在列表初始化中使用顶级转换.

我想知道是否给定两个类型TU,有可能它是实现定义的转换是否TU正在缩小.根据我对标准的解读,情况就是如此.这是我的推理:

  • 根据dcl.init.list(8.5.4)第7段,转换可以缩小的一种方式是,如果它是一个隐式转换,"从整数类型或无范围枚举类型到整数类型,不能代表原始值的所有值类型".
  • 考虑从unsigned int到的隐式转换long.
  • 关于的相对尺寸intlong,C++只要求sizeof(int) <= sizeof(long).
  • 考虑一个实现A,其中sizeof(int) == sizeof(long).在这个实现中,long不能代表所有的值unsigned int,所以转换会缩小.
  • 考虑一个实现B,其中sizeof(int) < sizeof(long).在此实现中,long可以表示所有值unsigned int,因此转换不会缩小.

我的分析是否正确,可以通过实现来定义转换是否正在缩小?这是可取的吗?

c++ implicit-conversion c++11 list-initialization

6
推荐指数
1
解决办法
278
查看次数

违约gtor 4.6和4.7之间的差异

在GCC 4.6.1上,当我声明一个具有默认构造函数的我自己的类型的实例时,如果我实例化该类型的对象并用大括号(如Foo my_foo {};)初始化它,那个类中的POD成员如果没有声明其他构造函数,则只会进行零初始化.如果除了默认的构造函数之外没有其他构造函数,它们将像预期的那样零初始化.

但是,在GCC 4.7.3上,零初始化以任何一种方式发生,这是我预期的行为.

这有什么区别?这是编译器错误吗?这两个GCC版本都支持C++ 11标准的默认构造函数.

没有必要坚持旧的GCC版本,但我想了解这里发生了什么.

注意:我是默认主要的ctor,op =.并且复制ctor只是为了保持类型可用于可变参数函数(clang要求将类分类为POD,尽管gcc让我使用具有可变函数的类型,即使用户定义的主ctor.奖励积分,如果你能告诉我我为什么.)

这是一个示例程序,包括底部的一些输出(来自使用两个GCC版本编译的二进制文件):

#include <cstdio>

// pod and pod_wctor are identical except that pod_wctor defines another ctor

struct pod {
    pod( void ) = default;
    pod( const pod& other ) = default;
    pod& operator=( const pod& other ) = default;

    int x,y,z;
};

struct pod_wctor {
    pod_wctor( void ) = default;
    pod_wctor( const int setx, const int sety, const int setz ) : x(setx), y(sety), z(setz) { }
    pod_wctor( const pod_wctor& …
Run Code Online (Sandbox Code Playgroud)

c++ gcc default-constructor c++11 list-initialization

6
推荐指数
1
解决办法
463
查看次数

Braced-init-lists和函数模板类型推导顺序

我有关于函数模板参数类型推导过程的问题.

举个例子:

#include <vector>
#include <sstream>
#include <string>
#include <iterator>
#include <fstream>

int main()
{
    std::ifstream file("path/to/file");
    std::vector<int> vec(std::istream_iterator<int>{file},{}); // <- This part
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我理解正确,第二个参数推断为std::istream_iterator默认构造函数的类型.

适当的std::vector构造函数声明为:

template <class InputIterator>
         vector (InputIterator first, InputIterator last,
                 const allocator_type& alloc = allocator_type());
Run Code Online (Sandbox Code Playgroud)

由于推导出第一个参数类型,因为std::istream_iterator<int>第二个参数也被推导出来std::istream_iterator<int>,因此可以应用统一初始化语义.我不知道的是类型推导发生的顺序.我真的很感激这方面的一些信息.

提前致谢!

c++ templates c++11 list-initialization type-deduction

6
推荐指数
1
解决办法
324
查看次数

如何构造具有唯一指针的向量

我尝试用unique_ptr 构造一个向量。但是我没有找到直接的方法。以下代码无法编译。错误是:调用 'std::__1::unique_ptr >' 的隐式删除复制构造函数:

#include <iostream>
#include <memory>
#include <utility>
#include <vector>
class test1{
public:
    test1(){};
    test1(test1&&)=default;
};

int main(int argc, const char * argv[]) {
    std::unique_ptr<test1> us(new test1());
    std::vector<std::unique_ptr<test1>> vec{move(us)};
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ initializer-list unique-ptr c++11 list-initialization

6
推荐指数
2
解决办法
4041
查看次数

什么时候编译器允许优化自动+大括号样式初始化?

假设您有一个名为Product的类,定义如下:

class Product
   {
   public:
      Product(const char *name, int i);
      Product(Product &&rhs);
      Product(const Product &rhs);
      ~Product();
   private:
      const char *m_name;
      int m_i;
   };
Run Code Online (Sandbox Code Playgroud)

并初始化一个这样的变量:

auto p = Product{"abc",123};
Run Code Online (Sandbox Code Playgroud)

我认为标准规定编译器必须在逻辑上执行以下操作:

  • 构建临时产品
  • move-construct p(使用临时产品)

但是允许编译器优化它以便直接构造p.

我验证了这一点(Visual Studio 2013),实际上,即使我们有自己的自定义(非默认)移动构造函数,编译器也会优化它.这可以.

但是,如果我明确删除了copy-和move-构造函数,如下所示:

class Product
   {
   public:
      Product(const char *name, int i);
      Product(Product &&rhs) = delete;
      Product(const Product &rhs) = delete;
      ~Product();
   private:
      const char *m_name;
      int m_i;
   };
Run Code Online (Sandbox Code Playgroud)

auto +大括号初始化仍然编译.我虽然编译器必须防止这种情况,因为没有复制或移动允许.

奇怪的是,如果我将删除的copy-和move-构造函数设为私有,如下所示:

class Product
   {
   public:
      Product(const char *name, int i);
      ~Product();
   private:
      Product(Product &&rhs) = …
Run Code Online (Sandbox Code Playgroud)

c++ auto list-initialization visual-studio-2013

6
推荐指数
1
解决办法
174
查看次数

作为参数的空初始化列表不调用默认构造函数

以下代码

class A {
public:
    A() {} // default constructor
    A(int i) {} // second constructor
};
int main() {
    A obj({});
}
Run Code Online (Sandbox Code Playgroud)

调用第二个构造函数.可能将空initializer_list视为一个参数并转换为int.但是当你从类中删除第二个构造函数时,它会调用默认的构造函数.为什么?

另外,我理解为什么A obj { {} }总是会调用带有一个参数的构造函数,因为我们传递的是一个空的参数initializer_list.

c++ c++11 list-initialization

6
推荐指数
1
解决办法
360
查看次数

std :: array <std :: vector>中的brace elision

我正在编译使用g++C++ 17.我有以下内容:

std::array<std::vector<int>, 2> v = {{ {1,2}, {3,4} }};
Run Code Online (Sandbox Code Playgroud)

我不明白为什么如果我删除数组的双括号它不再工作.

std::array<std::vector<int>, 2> v = { {1,2}, {3,4} }; // Does not compile
Run Code Online (Sandbox Code Playgroud)

我理解一般是如何std::array工作和双括号的需要,但正如我正在编译C++ 17我期望支持elision发挥作用.

为什么括号不适用于此?

c++ list-initialization c++17

6
推荐指数
2
解决办法
263
查看次数

{}和等号变量之间的差异

我是C ++编程的新手。我在Google的任何地方都找不到我的答案,因此希望可以在这里回答。

以下之间有区别吗

unsigned int counter{ 1 };
Run Code Online (Sandbox Code Playgroud)

要么

unsigned int counter = 1;
Run Code Online (Sandbox Code Playgroud)

这本书使用了第一种选择,它使我感到困惑,因为它没有解释差异。以下是我正在关注的书中的以下代码。

#include <iostream>
#include <iomanip>
#include <cstdlib> // contains function prototype for rand()
using namespace std;

int main()
{
    for (unsigned int counter{ 1 }; counter <= 20; ++counter) {
        cout << setw(10) << (1 + rand() % 6);

        // if counter is divisible by 5, start a new line of output
        if (counter % 5 == 0) {
            cout << endl;
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

c++ variables for-loop initialization list-initialization

6
推荐指数
2
解决办法
162
查看次数

如果使用 {},函数调用不会产生歧义

#include <stdio.h>
#include <vector>
#include <deque>

// 1st function
void f(int i, int j = 10){
    printf("Hello World what");
};

void f(std::vector<int>){
    printf("Hello World vec");
};

void f(std::deque<int>){
    printf("Hello World deq");
};

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

如果第一个函数被注释掉,我会ambiguous call在编译时得到。如果没有注释掉,则调用第一个函数。为什么{}隐式转换为int?

实例:https : //onlinegdb.com/rkhR0NiBD

c++ initialization curly-braces list-initialization c++17

6
推荐指数
2
解决办法
77
查看次数