请参阅此示例:https : //godbolt.org/z/5PqYWP
为什么这个对数组不能以与对向量相同的方式初始化?
#include <vector>
#include <array>
int main()
{
std::vector<std::pair<int,int>> v{{1,2},{3,4},{5,6}}; // succeeds
std::array <std::pair<int,int>, 3> a{{1,2},{3,4},{5,6}}; // fails to compile
}
Run Code Online (Sandbox Code Playgroud) 任何人都可以帮助我解决以下问题吗?
有一个简单的代码:
#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)
我真的不明白第一个代码有什么问题.
考虑以下功能
template <class... T, class... U>
void f(std::tuple<T...> t, std::tuple<U...> u)
{
std::cout << sizeof...(T) << " " << sizeof...(U) << std::endl;
}
int main(int argc, char* argv[])
{
f({3, 3.5, "Hello World!"}, {'a', std::string("b")}); // Fails
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在C++ 17中是否有任何方法可以修改函数签名,以便标记为"Fails"的行可以工作?(保持该线相同).
请考虑以下示例:
#include <iostream>
#include <string>
struct ABC
{
std::string str;
unsigned int id ;/* = 0 : error: no matching constructor for initialization of 'ABC'*/
};
int main()
{
ABC abc{"hi", 0};
std::cout << abc.str << " " << abc.id << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在定义结构ABC而没有id clang 3.x和gcc 4.8.x的默认值时,编译代码没有问题.但是,在为"id"添加默认参数后,我得到了流动的错误消息:
13 : error: no matching constructor for initialization of 'ABC'
ABC abc{"hi", 0};
^ ~~~~~~~~~
4 : note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 …Run Code Online (Sandbox Code Playgroud) 我发现对类使用初始化列表语法的可能性取决于类字段是否具有默认值.为什么?
确切地说,请考虑以下代码:
class S
{
public:
int a;
};
...
int a;
S s{ a };
Run Code Online (Sandbox Code Playgroud)
它编译没有任何问题.但是如果我在类字段中添加一个默认值,它就会停止构建:
class S
{
public:
int a = 0;
};
...
int a;
S s{ a };
Run Code Online (Sandbox Code Playgroud)
错误1错误C2440:'初始化':无法从'initializer-list'转换为'S'
为什么?还有什么影响这样的构造函数生成?
请考虑以下代码:
#include <array>
struct A
{
int a;
int b;
};
static std::array<A, 4> x1 =
{
{ 1, 2 },
{ 3, 4 },
{ 5, 6 },
{ 7, 8 }
};
static std::array<A, 4> x2 =
{
{
{ 1, 2 },
{ 3, 4 },
{ 5, 6 },
{ 7, 8 }
}
};
static std::array<A, 4> x3 =
{
A{ 1, 2 },
A{ 3, 4 },
A{ 5, 6 },
A{ 7, 8 …Run Code Online (Sandbox Code Playgroud) 这是关于这个的第n个问题,但我找不到完全相同的...
假设以下代码:
#include <iostream>
struct S {
int x;
int y;
};
class C {
public:
S s;
C() : s{123, s.x} {}
};
int main() {
std::cout << C().s.y << '\n';
}
Run Code Online (Sandbox Code Playgroud)
可以s.y像这样初始化吗?(只有JetBrains的ReSharper通过以下方式抱怨它:) Object member this->s.x might not be initialized.
如果有人用标准引用确认答案,那就太好了.
使用 C++20,可以为别名模板生成推导准则(请参阅https://en.cppreference.com/w/cpp/language/class_template_argument_deduction 上的“别名模板的推导”部分)。然而,我无法让它们使用聚合初始化语法。在这种情况下,似乎没有生成别名的扣除指南。
看这个例子:
#include <array>
template <size_t N>
using mytype = std::array<int, N>;
// Deduction guideline ???
int main() {
// mytype error_object = {1, 4, 7}; // ERROR
mytype<3> object = {1, 4, 7}; // OK, but I have to manually specify the size.
return object[0];
}
Run Code Online (Sandbox Code Playgroud)
我曾尝试编写演绎指南,但每次都会出现编译器错误。
template <typename T, typename ... U>
mytype(T, U...) -> mytype<1+sizeof...(U)>; // Compiler error
Run Code Online (Sandbox Code Playgroud)
以及我能想到的任何其他准则。
甚至可以自动推导出数组别名的大小吗?
我正在使用 GCC 10.2
c++ aggregate-initialization template-aliases c++20 deduction-guide
可以说我们有以下代码:
#include <iostream>
#include <string>
struct A
{
A() {}
A(const A&) { std::cout << "Copy" << std::endl; }
A(A&&) { std::cout << "Move" << std::endl; }
std::string s;
};
struct B
{
A a;
};
int main()
{
B{A()};
}
Run Code Online (Sandbox Code Playgroud)
在这里,我认为struct A不是一个聚合,因为它既有非平凡的构造函数,也有std::string我认为不是聚合的成员.这可能意味着它B也不是一个聚合体.
然而,我可以聚合初始化B.此外,这可以在没有调用复制或移动构造函数的情况下完成(例如,在ideone上的C++ 0x GCC 4.5.1 ).
这种行为似乎是一种有用的优化,特别是对于没有廉价移动的大型堆栈类型的组合.
我的问题是:这种聚合初始化何时在C++ 0x下有效?
编辑+跟进问题:
下面的DeadMG回答如下:
这根本不是聚合初始化,它是统一初始化,基本上在这种情况下意味着调用构造函数,并且没有复制或移动可能由RVO和NRVO完成.
请注意,当我更改B为以下内容时:
struct B
{
A a;
B(const A& a_) : a(a_) {}
B(A&& a_) : a(std::move(a_)) {} …Run Code Online (Sandbox Code Playgroud) 这有效:
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++ ×10
c++11 ×6
stdarray ×2
aggregate ×1
c++17 ×1
c++20 ×1
constructor ×1
g++4.8 ×1
optimization ×1
tuples ×1