如果您可以接受 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),您可以优先考虑一个版本或另一个通过(通过示例)@987654331 @值并在首选版本中接收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
}