具有std :: variant和std :: visit的并集模板

问题描述

我使用的是模板库,由于在我的代码中模板参数之一可以假定一定范围的值,因此我建议在建议下使用std :: variant并在其中声明所有可能的对象需要:

std::variant<TemplateClass<1>,TemplateClass<2>,...,TemplateClass<5>>

我从未使用过该实用程序。

要访问TemplateClass的方法,我必须使用std::visit,但有时它可以工作,而另一些则不起作用,例如说no member function XXX in std::variant < .... >或“在实例化函数模板专门化...”中[甚至不明白这里出了什么问题]

具体来说,我正在使用Eigen::Tensor库,当我调用rank()dimension(n)之类的方法时,它可以工作,而对于dimensions()和{{1} }不会。

在我的实施草案下方

setRandom()

我以错误的方式使用std::variant<Eigen::Tensor<double,1>,Eigen::Tensor<double,2>,/* ... */> makeTensor( int i,const std::initializer_list<int> dims) { switch (i) { case 1: { Eigen::Tensor<double,1> T1; T1.resize(dims); return T1; } case 2: { Eigen::Tensor<double,2> T2; T2.resize(dims); return T2; } /* ... */ } } int main() { auto myTensor{makeTensor(2,{4,5})}; // Tensor 2D 4x5 // Working methods auto rnk = std::visit([](const auto &tensor) { return tensor.rank(); },myTensor); auto dim1 = std::visit([](const auto &tensor) { return tensor.dimension(0); },myTensor); // Not working methods auto dimsTens = std::visit([](const auto &tensor) { return tensor.dimensions(); },myTensor); // 5 times same error saying //'In instantiation of function template specialization 'std::visit<(lambda at /// home/virginie/Desktop/Project/main.cpp:62:33),// std::variant<Eigen::Tensor<double,1,long>,2,3,// long>,4,5,long>> &>'' std::visit([&myTensor]() { myTensor.setRandom(); }); // 'No member setRandom() in std::variant<...>' } 吗?

----编辑----

在@florestan的建议下,我解决了与std::visit相关的问题,而使用dimensions()我得到了以下信息:

在/..../ main.cpp包含的文件

enter image description here

从这里需要

enter image description here

解决方法

您需要为所有可能的替代方法返回相同的类型。对于dimension,例如,您需要将数组元素复制到向量。

类似的事情应该有所帮助:

 auto dimsTens=std::visit(
    [](const auto &tensor) {
       auto dims = tensor.dimensions();
       return std::vector<int>(dims.begin(),dims.end());
    },myTensor);

第二个错误是因为您未正确调用std::visit。它需要两个参数,第一个是函数,第二个是变量。以下应该起作用。

std::visit([](auto& t){ t.setRandom();},myTensor); 

实时代码: https://godbolt.org/z/vq4PYo