我使用的类封装了模板专门化的std::变体,例如:
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_;};我试图使用转换移动构造函数从Generic_node中的函数构造一个Generic_node,但是编译失败了。
我定义了一个模板构造函数,它接受一个rvalue引用(假设一个专门的类),并通过将值移动到变量来构造变量,在该变量中,我希望调用转换移动构造函数# (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)这个问题很可能与变体无关,而与变量构造函数的模板实例化中的Base<T> == Derived相等有关,编译器似乎没有看到这一点。
模板实例化中发生了什么,为什么编译器不能调用提供的构造函数?
编辑:由于我打算创建一个专门化,我忘记了继承不能意味着类类型相等,即使技术上是在这种特殊情况下。因此,这是一项从专门基地转移而来的容易构建的任务:
struct Derived : Base<int>
{
Derived() = default;
Derived(Base<int>&&) {}
};如果我是正确的,则需要为Base的每个派生类显式定义构造函数。
发布于 2018-07-19 19:09:17
在您要给出的示例中,派生类是一个独立于Base的类。它们有完全相同的成员,相同的方法,但它们仍然是独立的类。
解决这个问题的最简单方法是使用using语句,而不是将其声明为单独的类:
using Derived = Base<int>;https://stackoverflow.com/questions/51429511
复制相似问题