Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 混合了重载的函数模板_C++_Templates_Overloading - Fatal编程技术网

C++ 混合了重载的函数模板

C++ 混合了重载的函数模板,c++,templates,overloading,C++,Templates,Overloading,因此,我想创建一个函数,将文本文件中的数据读取到各种矩阵中。 第一个是一个特征矩阵矩阵,您可以使用括号访问元素。 例如,mat(1,2)。第二种类型是vector对嵌套的向量情况使用部分特化*,对各种特征类使用一般情况,如下所示: template <typename T> void foo(vector<vector<T>>& mat) { // code that uses mat[x][y] } template <typenam

因此,我想创建一个函数,将文本文件中的数据读取到各种矩阵中。
第一个是一个
特征矩阵
矩阵,您可以使用括号访问元素。

例如,
mat(1,2)
。第二种类型是
vector对嵌套的向量情况使用部分特化*,对各种特征类使用一般情况,如下所示:

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)
}
模板
void foo(向量和矩阵){
//使用mat[x][y]的代码
}
模板
void foo(T&mat){
//使用mat(x,y)的代码
}

(*是的,我知道学究们会指出,从技术上讲,这不是“局部专门化”,而是“偏序函数重载”。

如果您可以接受C++11解决方案,那么使用SFINAE检查类型
T
是否可以支持
T()(0U,0U)
T()[0U][0U]

如果
T
不支持这两种操作,则此操作应该可以工作

以下是一个工作示例(其中
bar
substitute
Eigen


因此,我不明白为什么在应用于
向量
对象时会调用第一个模板函数。是因为它是先定义的吗?第一个函数似乎是“更专业化”的,或者是向量的什么:这是为什么?什么样的规则可以解决歧义?你写的似乎确实有效。我为
vector
编写了第三个模板函数,它似乎在3个选项之间做出了正确的选择。我只是不想在不知道它是如何工作的情况下使用它,让它有一天出问题。是的,越专业的过载就越成功。详细规则可以在C++标准中标记的[Tim.Fuff.Pix]部分(当前草案中的第14节),在早期版本中可能有不同的数字。在不明确的情况下(例如,如果有两个参数,在不同的重载中以不同的方式专门化),有时可能会出现编译错误,因为编译器无法明确地选择一个“最专门化”的版本,但在这种情况下,选择哪一个总是很清楚的。
#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
 }
#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 
 }