Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.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++;模板参数赋值推导_C++_Templates_Matrix - Fatal编程技术网

C++ C++;模板参数赋值推导

C++ C++;模板参数赋值推导,c++,templates,matrix,C++,Templates,Matrix,我想要一个非常简单的模板函数,它只在返回类型中包含模板参数,而不在函数参数中。然后,在调用函数时,应根据赋值推断模板参数 具体来说,让我们考虑一个函数,它创建了某个维度的类型 MatType < /代码>的随机矩阵。模板参数T是矩阵的数字类型(例如,双精度矩阵、浮点、整数等): 模板 MatType randmat(内部m,内部n) {//创建大小为m x n的MatType,用随机数填充并返回它。} 现在由于某种原因,模板参数不能从返回类型中推断出来,所以当我使用这个函数时,我必须将其称为

我想要一个非常简单的模板函数,它只在返回类型中包含模板参数,而不在函数参数中。然后,在调用函数时,应根据赋值推断模板参数

具体来说,让我们考虑一个函数,它创建了某个维度的类型<代码> MatType < /代码>的随机矩阵。模板参数T是矩阵的数字类型(例如,双精度矩阵、浮点、整数等):

模板
MatType
randmat(内部m,内部n)
{//创建大小为m x n的MatType,用随机数填充并返回它。}
现在由于某种原因,模板参数不能从返回类型中推断出来,所以当我使用这个函数时,我必须将其称为

MatType<double> M = randmat<double>(10,10);
mattypem=randmat(10,10);
但是,我想找到一种解决方法,即调用函数

MatType<double> M = randmat(10,10);
mattypem=randmat(10,10);
i、 e.让函数根据返回类型
MatType
确定模板参数。 这只是部分原因,因为我很懒,因为在我的例子中,模板参数可能会变得很长,很讨厌

这似乎是一个许多人以前问过的愚蠢的问题,但我并没有找到任何令人满意的答案,只是说这是不可能的。然而,我使用的是一个名为的矩阵库,它具有精确的模板函数,因此我知道这是可能的(但对于我来说,从源代码中提取它是如何完成的,这太复杂和耗时了)

这可以通过一些特性或模板元编程来实现吗?还有,如何处理没有赋值的函数调用,比如
randmat(10,10)


谢谢

你所问的并不完全可能,但其中的某些方面可能“偶然”起作用,这取决于问题的领域

排队

MatType<double> M = randmat(10,10);

因此,您必须在代码中提交特定于逻辑默认值的返回类型。考虑到您这样做,并且大多数代数/随机生成操作远比简单的副本转换复杂,在这种情况下,对我来说这似乎是一个复杂的过度操作。

一个选项是返回MapType

MatType<int>
randmat(int m, int n)
{ // create MatType<int> of size m x n, fill with random numbers and return it.}
MatType
randmat(内部m,内部n)
{//创建大小为m x n的MatType,用随机数填充并返回它。}
并有一个转换运算符来生成所需的类型

template<typename T>
struct MatType
{
   template<typename T>
   operator MatType<T>()
   {...}
};
模板
结构MatType
{
模板
运算符MatType()
{...}
};

更有效地实现此效果的一种方法是延迟随机值的计算,直到已知返回类型。您可以使用代理对象来实现这一点,代理对象的唯一目的是检测要分配给的类型,然后使用适当类型的对象执行计算

struct RandMatType {
    const int m_;
    const int n_;
    RandMatType (int m, int n) : m_(m), n_(n) {}
    template <typename T>
    operator MatType<T> () const {
        MatType<T> M;
        //... fill M
        return M;
    }
};

RandMatType randmat(int m, int n) {
   return RandMatType(m, n);
}
struct RandMatType{
const int m_;
康斯特国际公司;
RandMatType(int m,int n):m_u(m),n_u(n){
模板
运算符MatType()常量{
M型;
//…填充M
返回M;
}
};
RandMatType randmat(整数m,整数n){
返回RandMatType(m,n);
}

在上面的代码中,
randmat()
首先返回类型为
randmatype
的代理。然后,在赋值过程中,代理对象被转换为目标类型。然后,转换运算符假定转换类型是要使用的矩阵类型。

避免重复的简单解决方案是:

auto m = randmat<double>(10, 10);

autom=randmat(…)这可能取决于哪些复制构造函数可用于
MatType
和/或它们是否是
explicit
。您链接到的犰狳文档显示
mat A=randu(5,6)作为示例。因此,在模板参数中指定矩阵的类型,使用
randmat(10,10)
而不使用显式元素或矩阵类型实际上是个坏主意,因为实际上在复合表达式中无法可靠地使用
randmat(10,10)
。例如,以这个简单的复合表达式为例:
M=2+randmat(10,10)
,其中由
randmat(10,10)
生成的底层元素类型实际上是未知的。它应该是整数、浮点、双精度、复数等吗?为了避免这个问题,犰狳需要显式指定矩阵类型。默认模板参数恰好是
@Rumburak yes不幸的是,文档没有提到它在没有指定模板参数的情况下也可以工作,因此
mat A=randu(5,6)也可以工作。正如@mtall所指出的,在这种情况下,默认模板参数只是
mat
,它是double.Concur的矩阵。与我的产品类似,但转换是通过
MatType
构造函数而不是
randmat
转换运算符完成的。事实上,这也是一个不错的解决方案!但是您需要显式地向matrix类添加一个额外的构造函数(我不能,因为我使用的是库)。无论如何谢谢你!因此,使用这种方法,基本上必须从顶层开始,例如,始终生成复杂的双随机矩阵,然后可以将其向下转换为复杂的单、双、单、整数、无符号整数等。这似乎是一种实用的解决方案:-)但如果处理复杂的数据类型,效率不是很高(在我的情况下,这样做很好)这是一种非常聪明的方法!在实际分配给某个特定类型的特定矩阵对象之前,RandMatType只存储相关信息,即维度(可能还有概率分布等)只有在赋值时,随机矩阵才会被构造。我没有想到使用自定义转换,这些对我来说仍然有点奇怪:-)非常感谢!犰狳就是这么做的?它创建一个双随机矩阵,然后将其转换为其他类型?那么,对于复杂类型,这将如何工作(您缺少虚部)?无论如何,谢谢澄清!我刚刚注意到将犰狳的randn分配给一个复杂矩阵
cx\u ma
struct RandMatType {
    const int m_;
    const int n_;
    RandMatType (int m, int n) : m_(m), n_(n) {}
    template <typename T>
    operator MatType<T> () const {
        MatType<T> M;
        //... fill M
        return M;
    }
};

RandMatType randmat(int m, int n) {
   return RandMatType(m, n);
}
auto m = randmat<double>(10, 10);
struct randmat
{
    int x, y; 
    randmat(int x, int y): x(x), y(y) {}
};

template<typename T>
struct MatType
{
   int x, y;

   MatType(randmat r): x(r.x), y(r.y)
   {
       // call your random generation code here; can use T
   }
};

int main()
{
   MatType<double> m = randmat(10, 10);
}