这个程序合法吗?
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++ 11形式化了缩小转换的概念,并禁止在列表初始化中使用顶级转换.
我想知道是否给定两个类型T
和U
,有可能它是实现定义的转换是否T
对U
正在缩小.根据我对标准的解读,情况就是如此.这是我的推理:
unsigned int
到的隐式转换long
.int
和long
,C++只要求sizeof(int) <= sizeof(long)
.sizeof(int) == sizeof(long)
.在这个实现中,long
不能代表所有的值unsigned int
,所以转换会缩小.sizeof(int) < sizeof(long)
.在此实现中,long
可以表示所有值unsigned int
,因此转换不会缩小.我的分析是否正确,可以通过实现来定义转换是否正在缩小?这是可取的吗?
在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) 我有关于函数模板参数类型推导过程的问题.
举个例子:
#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>
,因此可以应用统一初始化语义.我不知道的是类型推导发生的顺序.我真的很感激这方面的一些信息.
提前致谢!
我尝试用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) 假设您有一个名为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)
我认为标准规定编译器必须在逻辑上执行以下操作:
但是允许编译器优化它以便直接构造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) 以下代码
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
.
我正在编译使用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 ++编程的新手。我在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) #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
?
c++ ×10
c++11 ×6
c++17 ×2
auto ×1
curly-braces ×1
for-loop ×1
gcc ×1
templates ×1
unique-ptr ×1
variables ×1