- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
#include <iostream>
#include <memory>
class Base
{
public:
Base() {}
};
class Derived : public Base
{
public:
Derived() {}
Derived(std::initializer_list<std::pair<int, std::shared_ptr<Base>>>) {}
};
int main(int argc, char ** argv)
{
auto example = new Derived({
{ 0, std::make_shared<Derived>() }
});
return 0;
}
它正常工作( live preview ),但是当我尝试使用 std::make_shared
和 std::initializer_list
作为参数时,我得到了错误:
auto example = new Derived({
{ 0, std::make_shared<Derived>({
{ 0, std::make_shared<Derived>() }
}) }
});
正如您在 live preview 上看到的那样.
error: too many arguments to function...
只有当我这样做时它才有效(live preview):
auto example = new Derived({
{ 0, std::make_shared<Derived>(std::initializer_list<std::pair<int, std::shared_ptr<Base>>> {
{ 0, std::make_shared<Derived>() }
}) }
});
我想知道的是:为什么只有当我将 std::initializer_list
作为参数传递给 std::make_shared
而不是使用 { {}}
就像这样:
auto example = new Derived({ { 0, std::make_shared<Base>() } });
是否可以让 std::make_shared
接受它?
提前致谢。
最佳答案
原因
auto example = new Derived({
{ 0, std::make_shared<Derived>() }
});
有效的是编译器知道它必须匹配初始化器
{{ 0, std::make_shared<Derived>() }}
不知何故与构造函数
Derived::Derived(std::initializer_list<std::pair<int, std::shared_ptr<Base>>>) {}
所以很明显初始化列表的元素,
{ 0, std::make_shared<Derived>() }
需要用于初始化std::pair<int, std::shared_ptr<Base>>
.然后它找到一个包含两个元素的对的构造函数,
pair::pair (const first_type& a, const second_type& b);
在哪里 first_type
是 int
和 second_type
是 std::shared_ptr<Base>
.所以最后我们看到参数 std::make_shared<Derived>()
隐式转换为 std::shared_ptr<Base>
,我们可以开始了!
在上面,我指出编译器通过寻找一个构造函数来处理初始化列表,该构造函数直接接受初始化列表或适当数量的参数,然后在适当的隐式转换后将初始化列表的元素传递给该构造函数如有必要。例如,编译器可以确定您的 std::shared_ptr<Derived>
需要隐式转换为 std::shared_ptr<Base>
在上面的例子中只是因为对的构造函数需要它。
现在考虑
std::make_shared<Derived>({
{ 0, std::make_shared<Derived>() }
})
问题是make_shared<Derived>
是一个部分专用的函数模板,可以接受任意数量和类型的参数。因此,编译器不知道如何处理初始化列表
{{ 0, std::make_shared<Derived>() }}
重载解析时不知道需要转换成std::initializer_list<std::pair<int, std::shared_ptr<Base>>>
.此外,braced-init-list 永远不会被推导出为 std::initializer_list<T>
通过模板扣除,所以即使你有类似的东西
std::make_shared<Derived>({0, 0})
和Derived
有一个合适的构造函数采用 std::initializer_list<int>
,它仍然无法工作,原因相同:std::make_shared<Derived>
将无法为其参数推断出任何类型。
如何解决这个问题?不幸的是,我看不到任何简单的方法。但至少现在你应该知道为什么你写的东西不起作用了。
关于c++ - std::make_shared 与 std::initializer_list,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24234480/
我需要使用 initializer_list 来初始化编译时大小的类数组。我已经知道我可以使用参数包构造函数并当场初始化它,但在这种情况下我需要使用 initializer_list。如果可能,我还想
我有一个类构造函数接受一个 initializer_list 这个构造函数必须运行接受一个的父类构造函数 initializer_list>. 所以我必须将初始化列表转换为二维初始化列表。 {1, 2
这个问题在这里已经有了答案: 关闭10 年前。 Possible Duplicate: initializer_list and move semantics 环境:Linux,g++-4.7 我使
以下代码编译并运行: #include #include #include #include void ext( std::initializer_list >> myList ) {
std::vector的初始化列表构造函数具有以下形式 vector( std::initializer_list init, const Allocator& alloc = Allocator()
考虑以下代码片段... void boo(std::initializer_list l) { } template void foo(std::initializer_list l) {
我的问题是关于 std::initializer_list 之间缺乏转换当这些转换看起来很容易实现时,包含的类型或多或少是 cv 限定的类型。 考虑以下无效代码: std::initializer_l
我的图表构造函数: Graph(std::initializer_list list); 我的边缘构造函数: Edge(int out, int in); 我想通过以下方式创建我的图表: Graph
我有一些我想在编译时由需要某种程度验证的初始化列表初始化的类。 我首先尝试使用static_assert,但不会与错误“静态声明的非恒定条件”一起编译 造成此错误的最佳方法是什么? class foo
//parameter pack sum example constexpr int sum(int N= 0) { return N; } template constexpr int su
我是新来的,这是我的第一个问题。 所以,我有这个功能: std::string join(string_initializer_list p_input) const { std::strin
想问一下有没有机会补上引用功能。假设我有功能: double refce( double (&f1)(double), double in ){ return f1(in); } 而不是这样调
所以我昨天尝试开始使用 std::initializer_list 但这并不是一个巨大的成功。这是我最后的尝试之一: #include #include struct XmlState
考虑函数: template void printme(T&& t) { for (auto i : t) std::cout ({'a', 'b', 'c'})); printme(st
考虑函数: template void printme(T&& t) { for (auto i : t) std::cout ({'a', 'b', 'c'})); printme(st
我想用 std::initializer_list 初始化基类。 struct A : public std::array { // This constructor works fine A
基于这段代码 struct Foo { Foo() { cout ilist) { cout 构造函数的大括号初始化中。 相反,复制构造函数带头。 你
尝试为 Node 安装 phash-image 但出现此错误: > phash-image@3.1.0 install /Users/jong/Workspace/mgmtio/phash-image
下面对 foo 的调用是否有效? GCC 似乎对此很满意,而 Clang 为 foo 给出了“无匹配函数”错误;以及无法推断出 N 的注释。 template void foo(const int
我正在尝试使用函数模板 foo 将参数转换为 initializer_list。但是,它转换的 initializer_list 具有与输入参数不同的奇怪值。 #include #include
我是一名优秀的程序员,十分优秀!