我有以下代码:
#include <iostream>
#include <vector>
struct C {
int a;
C() : a(0) {}
C(int a) : a(a) {}
};
std::ostream &operator<<(std::ostream &os, const C &c) {
os << c.a;
return os;
}
using T = std::vector<C>;
int main() {
auto v = T({5});
for (const auto &a : v) {
std::cout << a << ", ";
}
std::cout << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我使用 g++,它会打印:
#include <iostream>
#include <vector>
struct C {
int a;
C() : a(0) {}
C(int …Run Code Online (Sandbox Code Playgroud) c++ vector initializer-list compiler-specific direct-initialization
考虑以下代码:
struct S
{
S(int, double) {}
explicit S(const S&) {}
explicit S(S&&) {}
};
void i_take_an_S(S s) {}
S i_return_an_S() { return S{ 4, 2.0 }; }
int main()
{
i_take_an_S(i_return_an_S());
}
Run Code Online (Sandbox Code Playgroud)
使用“-std=c++17”标志,g++ 和 clang++ 都可以很好地编译此代码。然而,MSVC(带有 /std:c++17 标志)报告
“错误 C2664:'void i_take_an_S(S)':无法将参数 1 从 'S' 转换为 'S'”
作为编译错误,带有附加注释
“结构‘S’的构造函数被声明为‘显式’”。
根据C++17的初始化规则(第3点的解释)S,不应考虑使用复制构造函数来S初始化i_take_an_S;S(int, double)应该通过直接列表初始化选择精确匹配。
这可能是 MSVC 中的一个错误吗?
我一直认为对于与类类型不匹配的类型 T 的直接初始化和复制初始化是绝对相等的。但我似乎误会了。如果我复制初始化(使用=),下面的代码不会编译,并且只有当我通过括号()直接初始化时才编译(在任何情况下,代码在终止时都不起作用,但这是一个不同的故事,与这个问题)。
#include <future>
#include <cstdio>
int main()
{
/* This doesn't compile */
// std::packaged_task<int()> foo = []() -> int {
// return 10;
// };
/* This works */
std::packaged_task<int()> foo([]() -> int {
return 10;
});
auto fut = foo.get_future();
foo();
auto a = fut.get();
printf("a == %d\n", a);
}
Run Code Online (Sandbox Code Playgroud)
错误:
<source>: In function 'int main()':
<source>:8:37: error: conversion from 'main()::<lambda()>' to non-scalar type 'std::packaged_task<int()>' requested
8 | std::packaged_task<int()> foo = []() -> …Run Code Online (Sandbox Code Playgroud)