I'm using a template library and since in my code one of the template parameters can assume a finite range of values, I decided to use, under suggestion, std::variant and declare in it all the objects I will possibly need:
std::variant<TemplateClass<1>, TemplateClass<2>, ..., TemplateClass<5>>
I never used this utility.
To access the methods of TemplateClass I have to use std::visit, but sometimes it works and other it doesn't, say no member function XXX in std::variant < .... > or "In instantiation of function template specialization ... " [I don't even understand what is the problem here]
Specifically, I'm using Eigen::Tensor library and when I call methods like rank(), dimension(n), it works, while for methods like dimensions() and setRandom() it doesn't.
Below a draft of my implementation
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, 0, long>, Eigen::Tensor<double, 2, 0, long>, Eigen::Tensor<double, 3, 0,
// long>, Eigen::Tensor<double, 4, 0, long>, Eigen::Tensor<double, 5, 0, long>> &>''
std::visit([&myTensor]() { myTensor.setRandom(); }); // 'No member setRandom() in std::variant<...>'
}
Am I using std::visit in the wrong way?
---- EDIT ----
After the suggestion of @florestan, I have solved the problem related to dimensions(), while with setRandom I get the following:
In file included from /..../ main.cpp
required from here

You need to return the same type for all possible alternatives. In case of dimension, you need to copy the array elements to a vector, for example.
Something like this should help:
auto dimsTens=std::visit(
[](const auto &tensor) {
auto dims = tensor.dimensions();
return std::vector<int>(dims.begin(), dims.end());
}, myTensor);
The second error is because you don't call std::visit the right way. It needs two params, first the function and second the variant to visit. The following should work.
std::visit([](auto& t){ t.setRandom();}, myTensor);
Live code: https://godbolt.org/z/vq4PYo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With