所以我想创建一个函数,将文本文件中的数据读入各种矩阵
首先是Eigen
矩阵,您可以在其中访问带括号的元素
例如。 mat(1,2)
。第二类是类似vector<vector<T>
的类型,其中T
可以是int
,double
等。显然,可以使用方括号访问它们。
现在我需要为这两种情况创建一个模板。 Eigen
有许多矩阵类型(MatrixXd
,SparseMatrix
等),而vector<vector<T>>
可能有多种类型T
。
然而,如果我真正想要的是 我知道重载优先于模板,但它们都是模板化的!Eigen
的模板函数,如何确保vector<vector<T>>
的模板函数不会被调用? < / p>
我该怎么办?
答案 0 :(得分:2)
对嵌套向量的情况使用部分特化*,对各种特征类使用一般情况,如下所示:
template <typename T>
void foo(vector<vector<T>>& mat) {
// code that uses mat[x][y]
}
template <typename T>
void foo(T& mat) {
// code that uses mat(x,y)
}
(*是的,我知道学生们会指出,从技术上讲,这不是&#34;部分专业化&#34;但是&#34;部分有序的功能重载&#34;。)
答案 1 :(得分:1)
如果您可以接受C ++ 11解决方案,那么使用SFINAE检查类型T
是否可以支持T()(0U, 0U)
或T()[0U][0U]
呢?
如果T
不支持这两项操作,这应该有用。
以下是一个工作示例(其中bar
替换Eigen
)
#include <vector>
#include <iostream>
template <typename T>
auto foo (T & mat) -> decltype( mat[0U][0U], int() )
{ return 1; }
template <typename T>
auto foo (T & mat) -> decltype( mat(0U, 0U), int() )
{ return 2; }
struct bar
{
void operator() (std::size_t x, std::size_t y)
{ }
};
int main ()
{
std::vector<std::vector<int>> m1;
bar m2;
std::cout << foo(m1) << std::endl; // print 1
std::cout << foo(m2) << std::endl; // print 2
}
如果您必须使用同时支持[0U][0U]
和(0U, 0U)
的模板类(请参阅以下示例中的baz
),您可以优先考虑一个版本或另一个版本(例如)一个int
值,在首选版本中收到int
,在另一个版本中收到long
请参阅以下代码以获取示例
#include <vector>
#include <iostream>
template <typename T>
auto foo (T & mat, long) -> decltype( mat[0U][0U], int() )
{ return 1; }
template <typename T>
auto foo (T & mat, int) -> decltype( mat(0U, 0U), int() )
{ return 2; }
template <typename T>
int foo (T & mat)
{ return foo(mat, 0); }
struct bar
{
void operator() (std::size_t x, std::size_t y)
{ }
};
struct baz
{
std::vector<std::vector<int>> m;
std::vector<int> & operator[] (std::size_t x)
{ return m[x]; }
int & operator() (std::size_t x, std::size_t y)
{ return m[x][y]; }
};
int main ()
{
std::vector<std::vector<int>> m1;
bar m2;
baz m3;
std::cout << foo(m1) << std::endl; // print 1
std::cout << foo(m2) << std::endl; // print 2
std::cout << foo(m3) << std::endl; // print 2
}