Ant*_*vin 6 c++ copy-constructor type-traits c++11
这是std :: unordered_map <T,std :: unique_ptr <U >>可复制的后续内容吗?GCC错误?
所以想象我们创建了一个模板类Container:
template<class T>
class Container {
T t;
public:
Container() = default;
Container(const Container& other) : t(other.t) {}
};
Run Code Online (Sandbox Code Playgroud)
不幸的是,即使不是可复制的,is_copy_constructible它的产量true也是如此T:
static_assert(!std::is_copy_constructible<Container<std::unique_ptr<int>>>::value, "Copyable");
Run Code Online (Sandbox Code Playgroud)
由于上述问题的答案中描述的原因,此断言失败,此处还有关于此主题的另一个答案.
看来这可以通过制作这样的复制consructor模板来修复:
template<class T>
class Container {
T t;
public:
Container() = default;
template<typename U = void>
Container(const Container& other) : t(other.t) {}
};
Run Code Online (Sandbox Code Playgroud)
这适用于GCC和clang(static_assert不再失败).
问题:
从标准的角度来看,这是一种正确的is_copy_constructible工作方式吗?如果是,添加模板如何影响变量initialization(§20.9.4.3/6)的直接上下文的有效性?
(可选)有没有更正确或更直观的方法来执行此操作?
注意:声明复制构造函数default也可以实现此目标,但并非总是可行.
更新:现在我看到我的解决方案无效,因为复制构造函数不能是模板.这仍然为问题2留下了空间.
更新2:我从ecatmur的回答中改变了一些代码,将丑陋Container本身移出并使其可重用:
struct unused; // forward declaration only
template<class Container>
using const_ref_if_copy_constructible = typename std::conditional<
std::is_copy_constructible<typename Container::value_type>::value,
Container const&,
unused>::type;
template<typename T>
class Container {
T t;
public:
typedef T value_type;
Container() = default;
Container(const_ref_if_copy_constructible<Container> other) : t(other.t) {}
Container(Container&& other) : t(std::move(other.t)) {}
};
Run Code Online (Sandbox Code Playgroud)
但我仍然对此不太满意.对我来说,它似乎是C++标准中的一个缺陷,这些东西不能开箱即用.
那不是按照你的想法去做;模板构造函数永远不会被视为复制构造函数,因此通过添加template<typename U = void>到复制构造函数,您将诱导编译器创建其自己的默认复制构造函数。
一种可能性(缺少针对非复制构造类型的单独的类模板)是通过将其参数替换为与重载解析无关的内容来禁用复制构造函数:
struct unused; // forward declaration only
template<typename T>
class Container {
T t;
public:
Container() = default;
Container(
typename std::conditional<
std::is_copy_constructible<T>::value,
Container const&,
unused>::type other)
: t(other.t) {}
Container(Container&& other) : t(std::move(other.t)) {}
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
720 次 |
| 最近记录: |