c++ - 转换移动构造函数的模板特化的 std::variant
问题描述
我正在使用一个封装模板专业化的 std::variant 的类,例如:
template<typename Type> struct Generic_node {...};
struct Leaf_node : Generic_node<...> {...};
struct Inner_node : Generic_node<...> {...};
struct Node {std::variant<Leaf_node, Inner_node> variant_;};
我正在尝试使用转换移动构造Node
函数从函数构造一个Generic_node
,但编译失败。
我定义了一个模板构造函数,它接受一个右值引用(假设是一个专门的类)并通过将值移动到变体来构造变体,我希望在其中调用转换移动构造函数# (4)。
当我试图创建最小的非工作示例时,我发现问题实际上只从模板函数中显示出来,如果我知道确切的类型(Leaf_node == Generic_node<...>
编译器知道),移动构造就会成功。因此,我假设总是会发生一些我没有预料到的模板魔术。
#include <variant>
template<typename T>
struct Base
{
void f();
};
struct Derived : Base<int> {};
struct Variant
{
// In real program expecting the T to be one of the multiple variants
// Here I use only one variant because it suffices to illustrate the problem
template<typename T>
Variant(T&& t)
:
variant_ {std::move(t)}
{
}
std::variant<Derived> variant_;
};
template<typename T>
void
Base<T>::
f()
{
Variant {std::move(Derived {})}; // can call on exact type
Variant {std::move(Base<T> {})}; // can not call on specialized template type
}
int
main()
{
Derived {}.f();
}
相关编译器错误消息(clang 7,libstdc++-8):
note: candidate template ignored: substitution failure [with _Tp = Base<int>,
$1 = void, $2 = void]: implicit instantiation of undefined template
'std::variant<Derived>::__to_type_impl<18446744073709551615, false>'
variant(_Tp&& __t)
该问题很可能与变体无关,而是与 Variant 构造函数的模板实例化中的相等性有关Base<T> == Derived
,编译器好像没有看到。
模板实例化中发生了什么,为什么编译器不能调用提供的构造函数?
编辑:因为我打算创建一个专业化,我忘记了继承不能暗示类类型相等,即使它在技术上是在这种特殊情况下。因此,从专门的 Base 构造 Derived by move 是一项简单的任务:
struct Derived : Base<int>
{
Derived() = default;
Derived(Base<int>&&) {}
};
如果我是正确的,则需要为 Base 的每个派生类显式定义构造函数。
解决方案
在您给出的示例中,Derived 类是与 Base 分开的类。它们具有完全相同的成员、相同的方法,但它们仍然是独立的类。
解决它的最简单方法是使用using
语句而不是将其声明为单独的类:
using Derived = Base<int>;
推荐阅读
- javascript - 如何在 onChangeText 回调中立即更改文本?
- java - Spring数据ldap不持久用户但ldap模板有效
- python - 如何跟踪字符串中的符号以进行正确操作?
- java - 如何在testng中将值传递给@test
- java - 如何在 Spring Boot 中禁用某些警告
- maxima - 如何组合两个和并分解出一个共同的元素表达式?
- java - Java右移输出负值
- ios - Xamarin Visual Studio ios 模拟器不工作
- python - Python将列表添加到另一个列表的一部分
- go - 为什么/何时从另一个 goroutine 调用上下文取消函数会导致死锁?