另一个容器内的c ++容器
Posted
技术标签:
【中文标题】另一个容器内的c ++容器【英文标题】:c++ container inside another container 【发布时间】:2021-01-03 03:36:55 【问题描述】:#include <bits/stdc++.h>
template <typename T>
struct Row
Row() puts("Row default");
Row(const Row& other) puts("Row copy");
Row(Row&& other) puts("Row move");
Row(T x) puts("Row int");
;
int main()
Row<Row<int>> x (10); // this works
Row<Row<int>> x2 = 10; // error
为什么代码不起作用?我知道第一个执行直接初始化,第二个是复制初始化,但是当涉及到容器内的容器时,我对我来说并不容易。
编译器:clang c++20
错误信息:
从 'int' 到 'Row
' 的转换不可行
行
x2 = 10
【问题讨论】:
请创建一个minimal reproducible example - 任何拥有符合标准的编译器的人都可以编译的东西。提示:#include <bits/stdc++.h>
不包含标准标题。
你需要实现operator =(...)
。
【参考方案1】:
问题是copy initialization 比直接初始化更宽松:
> In addition, the implicit conversion in copy-initialization must produce T
directly from the initializer, while, e.g. direct-initialization expects
an implicit conversion from the initializer to an argument of T's constructor.
因为从int
初始化需要2 次转换(从int
到Row<int>
和从Row<int>
到Row<Row<int>>
),直接初始化允许它,但复制初始化不允许。您也可以在文档示例中看到它:
struct S S(std::string) ; // implicitly convertible from std::string
S s("abc"); // OK: conversion from const char[4] to std::string
S s = "abc"; // Error: no conversion from const char[4] to S
S s = "abc"s; // OK: conversion from std::string to S
【讨论】:
【参考方案2】:在
Row<Row<int>> x2 = 10;
您也提到了复制初始化,而不是调用赋值运算符。复制初始化调用对象的复制(或移动)构造函数,这要求您通过引用作为参数传递对象,这对于您传递的 int
10 显然是不可能的。为了使它工作,你必须提供一个有效的类型来复制:
Row<Row<int>> x2 = Row<int>(10);
来自copy-constructor reference:
类 T 的复制构造函数是一个非模板构造函数,其第一个参数是 T&、const T&、volatile T&或 const vola
【讨论】:
自 C++17 以来,复制初始化不一定调用复制/移动构造函数;这里有一个特殊的规则来防止第二次转换 ([over.best.ics]/4)。【参考方案3】:这是编译器可能会为第一次调用生成的(参考cppinsights)
/* First instantiated from: insights.cpp:12 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
struct Row<int>
inline Row();
inline Row(const Row<int> & other);
inline Row(Row<int> && other);
inline Row(int x)
puts("Row int");
;
#endif
/* First instantiated from: insights.cpp:12 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
struct Row<Row<int> >
inline Row();
inline Row(const Row<Row<int> > & other);
inline Row(Row<Row<int> > && other);
inline Row(Row<int> x)
puts("Row int");
;
#endif
int main()
Row<Row<int> > x = Row<Row<int> >(Row<int>(10));
你的输出将是
Row int Row int
Row int
来自第一个模板实例化和一个来自第二个模板实例化
当你尝试时
Row<Row<int>> x2 = 10;
编译器将10
转换为int
,但它可以找到可以直接将int
转换为Row<Row<int>>
的实例化。这将需要 2 次转换。
所以要么你自己提供一个转换,要么使用直接初始化。
【讨论】:
以上是关于另一个容器内的c ++容器的主要内容,如果未能解决你的问题,请参考以下文章
@FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本