给出:
ResolveSource
我可以做到:
<InstallExecuteSequence>
<ResolveSource After="CostInitialize"/>
<Custom Action="CustomActionThatNeedsRelativePath" After="CostFinalize"/>
</InstallExecuteSequence>
甚至...
struct X {
int m;
std::string s;
};
但不是...
X x; // invokes automatically defined default ctor
X y = { 5 }; // invokes whatever became of the original struct initialization but now maybe runs through C++ initializer-lists?
X z = { 5, "yolo" }; // I assume this is an initializer-list that is being handled by some rule for structs that either runs through a compiler created ctor or copy-from-initializer-list that is similarly compiler-created
我不了解初始化列表,隐式定义(或编译器定义)的ctor和转发功能(如std::vector<X> vx;
vx.push_back({ 99, "yo" }); // okay
)之间的规则
有人会好心地指出我标准的必要要点,还是一篇深入的讨论结构和隐式构造以及编译器提供的其他成员的所有规则的内容的好文章作为复制/移动运算符?
我似乎需要更全面的规则课程-因为看来vx.emplace_back(99, "yo"); // error VS 2017 v. 15.7.4
vx.emplace_back({99, "yo"}); // error VS 2017 v. 15.7.4
应该为emplace_back()
或emplace_back()
中的一个工作-不?>
答案 0 :(得分:6)
X
是aggregate。尽管聚合的特定定义在每个标准中均已更改,但是您的类型在所有标准中都是聚合。
聚集的列表初始化在此处进行聚集初始化。这里没有构造函数-没有“自动”构造函数,没有合成构造函数。聚合初始化不会创建构造函数,也不会通过该机制。我们正在从 braced-init-list 中的适当的初始化程序直接初始化每个类成员。这就是您的y
和z
所做的。
现在,对于第二部分。 vector
的相关部分如下:
template <typename T>
struct vector {
void push_back(T&&);
template <typename... Args>
void emplace_back(Args&&...);
};
与{99, "yo"}
类似的 braised-init-list 没有类型。而且您无法为其推断类型。它们只能在特定情况下使用。 push_back({99, "yo"})
可以正常工作,因为push_back
需要一个X&&
-它不是函数模板-我们知道如何进行初始化。
但是emplace_back()
是一个函数模板-它需要根据其参数类型推论Args...
。但是我们没有类型,没有什么可以推断的!这里有一些例外(特别是可以推断出std::initializer_list<T>
),但是在这里,我们陷入了困境。您将必须编写emplace_back(X{99, "yo"})
-在呼叫者一方创建X
。
类似地,emplace_back(99, "yo")
不起作用,因为emplace
使用()
进行初始化,但是您不能()
初始化聚合。它没有构造函数!