我如何使用演绎来选择 return 类型的函数
How do i use deduction to choose the return type of function
我对使用 C++11 标准的函数的完整推导有疑问。基本上,我应该制作一个函数,该函数采用单个参数,该参数看起来应该像一个矩阵(基本上是任何容器),其元素可以再次是任何容器,但请记住,每一行的元素不一定需要相同的大小。例如,参数可以是双端队列的向量、经典的类 C 矩阵、向量的向量、向量的双端队列等等,你明白了。话说回来。函数本身需要为具有相同结构和元素类型的二维矩阵动态分配(使用碎片而不是连续分配)内存,然后将给定矩阵中的所有元素复制到其中,最后 return 一个双指针,你可以用于访问矩阵的元素。话虽如此,我实际上并不知道如何使用完全推导,以便函数实际上知道哪种类型是它必须 return 的双指针。我首先想到的是使用这样的东西:
template <typename MatrixType>
auto CreateMatrix (MatrixType M) -> decltype ...
其背后的逻辑是完全推导会找出必须returned 的双指针类型,但是三个点 (...) 是我停止的地方,我实际上不知道该写什么那里。
当然我可以这样做:
template <typename MatrixType>
MatrixType** CreateMatrix (MatrixType M)
但它不使用推导,因为这样调用:
std::vector<std::deque<double>> a = {...};
auto x = CreateMatrix(a);
如果不在函数调用中使用 <double>
将无法工作,因此它不是一个完整的“问题已解决”,它只是一个廉价的技巧。
内存分配应该不难,我觉得做起来会很容易,但是目前我卡在这里,不知道该怎么办。
感谢您的每一次帮助!
我仍然不确定我是否理解你想要做什么。我将专注于实际问题:当容器可以由标准容器或 C 数组组成时,如何从 2D 容器推断值类型?
您可以使用类型特征。标准容器有一个 value_type
成员别名。当二维数组作为指针 T**
传递时,值类型为 T
。当通过引用传递数组 T[M][N]
时,值类型为 T
:
template <typename T>
struct value_type { using type = typename T::value_type; };
template <typename T>
struct value_type< T*> { using type = T; };
template <typename T,size_t N>
struct value_type< T[N] > { using type = T;};
template <typename T>
struct value_type2d {
using type = typename value_type<typename value_type<T>::type>::type;
};
作为示例,我使用了一个简单的函数 returns 第一个元素:
template <typename Matrix>
typename value_type2d<Matrix>::type foo(const Matrix& m) {
return m[0][0];
}
int main() {
std::vector<std::vector<double>> x{{42,1},{2,3}};
std::cout << foo(x) << "\n";
std::vector<std::deque<double>> y{{42,1},{2,3}};
std::cout << foo(x) << "\n";
int z[2][2] = {{42,1},{2,3}};
std::cout << foo(z) << "\n";
std::vector<std::string> w[2] = {{"42","1"},{"2","3"}};
std::cout << foo(x) << "\n";
}
PS:是的decltype( M[0][0] )
是获取值类型的更简单的方法。尽管例如 std::map::operator[]
不是 const
并且当函数不修改参数时,您不应该传递非常量引用。而且您当然不希望复制整个矩阵只是为了将其传递给函数。
我对使用 C++11 标准的函数的完整推导有疑问。基本上,我应该制作一个函数,该函数采用单个参数,该参数看起来应该像一个矩阵(基本上是任何容器),其元素可以再次是任何容器,但请记住,每一行的元素不一定需要相同的大小。例如,参数可以是双端队列的向量、经典的类 C 矩阵、向量的向量、向量的双端队列等等,你明白了。话说回来。函数本身需要为具有相同结构和元素类型的二维矩阵动态分配(使用碎片而不是连续分配)内存,然后将给定矩阵中的所有元素复制到其中,最后 return 一个双指针,你可以用于访问矩阵的元素。话虽如此,我实际上并不知道如何使用完全推导,以便函数实际上知道哪种类型是它必须 return 的双指针。我首先想到的是使用这样的东西:
template <typename MatrixType>
auto CreateMatrix (MatrixType M) -> decltype ...
其背后的逻辑是完全推导会找出必须returned 的双指针类型,但是三个点 (...) 是我停止的地方,我实际上不知道该写什么那里。
当然我可以这样做:
template <typename MatrixType>
MatrixType** CreateMatrix (MatrixType M)
但它不使用推导,因为这样调用:
std::vector<std::deque<double>> a = {...};
auto x = CreateMatrix(a);
如果不在函数调用中使用 <double>
将无法工作,因此它不是一个完整的“问题已解决”,它只是一个廉价的技巧。
内存分配应该不难,我觉得做起来会很容易,但是目前我卡在这里,不知道该怎么办。
感谢您的每一次帮助!
我仍然不确定我是否理解你想要做什么。我将专注于实际问题:当容器可以由标准容器或 C 数组组成时,如何从 2D 容器推断值类型?
您可以使用类型特征。标准容器有一个 value_type
成员别名。当二维数组作为指针 T**
传递时,值类型为 T
。当通过引用传递数组 T[M][N]
时,值类型为 T
:
template <typename T>
struct value_type { using type = typename T::value_type; };
template <typename T>
struct value_type< T*> { using type = T; };
template <typename T,size_t N>
struct value_type< T[N] > { using type = T;};
template <typename T>
struct value_type2d {
using type = typename value_type<typename value_type<T>::type>::type;
};
作为示例,我使用了一个简单的函数 returns 第一个元素:
template <typename Matrix>
typename value_type2d<Matrix>::type foo(const Matrix& m) {
return m[0][0];
}
int main() {
std::vector<std::vector<double>> x{{42,1},{2,3}};
std::cout << foo(x) << "\n";
std::vector<std::deque<double>> y{{42,1},{2,3}};
std::cout << foo(x) << "\n";
int z[2][2] = {{42,1},{2,3}};
std::cout << foo(z) << "\n";
std::vector<std::string> w[2] = {{"42","1"},{"2","3"}};
std::cout << foo(x) << "\n";
}
PS:是的decltype( M[0][0] )
是获取值类型的更简单的方法。尽管例如 std::map::operator[]
不是 const
并且当函数不修改参数时,您不应该传递非常量引用。而且您当然不希望复制整个矩阵只是为了将其传递给函数。