c++ - 带有 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()
,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, 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<...>'
}
我是否std::visit
以错误的方式使用?
- - 编辑 - -
在@florestan 的建议下,我解决了与 相关的问题dimensions()
,同时setRandom
得到以下信息:
解决方案
您需要为所有可能的替代方案返回相同的类型。例如,在 的情况下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);
推荐阅读
- google-apps-script - Google 表格到日历应用脚本 ColorId
- angular - 尝试使用 Angular firebase 创建 docReference
- node.js - ES6 Set 在简单的 Express Node.js 应用程序中不起作用
- c++ - 此错误:“C6262:函数使用'1600000620'字节的堆栈:超出/分析:stacksize'16384'。考虑将一些数据移动到堆”
- sql - While 循环 SQL Server
- sql-server - 选择值为最大值的行,并且一列为空
- credentials - Rails 6+:Rails 读取 SECRET_KEY_BASE 的顺序(env var 与 credentials.yml.enc)
- google-sheets - 谷歌工作表查询范围重置为 A:A
- excel - 选择“保存”时如何使宏运行?
- javascript - 如何为电子邮件进行 jQuery 域验证?