C++ 如何在虚拟方法上使用模板参数类?
我知道在虚拟方法上使用模板是不可能的,因为编译无法知道如何实现所有可能性,但我需要的是以受限的方式使用模板,如:C++ 如何在虚拟方法上使用模板参数类?,c++,oop,templates,c++11,C++,Oop,Templates,C++11,我知道在虚拟方法上使用模板是不可能的,因为编译无法知道如何实现所有可能性,但我需要的是以受限的方式使用模板,如: template<typename T, size_t N> class MatBase { public: static constexpr size_t order = N; using value_type = T; MatBase() = default; virtual ~MatBase() = default; template&l
template<typename T, size_t N>
class MatBase {
public:
static constexpr size_t order = N;
using value_type = T;
MatBase() = default;
virtual ~MatBase() = default;
template<class Fn = T(T)>
virtual void Map(Fn&& fn) = 0;
template<class Fn = T(T,T)>
virtual T Reduce(Fn&& fn) = 0;
};
模板
类MatBase{
公众:
静态constexpr size\u t order=N;
使用值_type=T;
MatBase()=默认值;
virtual~MatBase()=默认值;
模板
虚空图(Fn&&Fn)=0;
模板
虚拟T减少(Fn&&Fn)=0;
};
这意味着,Fn使用类上声明的模板,所以我认为编译器可以推断出所有可能的类型。有没有办法做到像C++那样?正如你所说的,你不能有模板化的虚拟函数。但是,为什么您需要模板呢?请参见下面的示例代码 示例代码
#包括
模板
类MatBase
{
公众:
静态constexpr size\u t order=N;
使用MapFn=T(*)(T);
使用ReduceFn=T(*)(T,T);
使用值_type=T;
MatBase()=默认值;
virtual~MatBase()=默认值;
虚空映射(MapFn&&fn){}
虚T Reduce(ReduceFn&&fn){}
};
int main()
{
基质m;
返回0;
}
一个更灵活的解决方案可以考虑使用<代码> STD::函数< /COD>(例如,<代码> STD::函数< /代码>)用于参数,因为它给调用方更多的灵活性。例如,调用方可以使用普通函数、成员函数、lambda表达式或functor对象。
如您所述,不能使用模板虚拟函数。但是,为什么您需要模板呢?请参见下面的示例代码 示例代码#包括
模板
类MatBase
{
公众:
静态constexpr size\u t order=N;
使用MapFn=T(*)(T);
使用ReduceFn=T(*)(T,T);
使用值_type=T;
MatBase()=默认值;
virtual~MatBase()=默认值;
虚空映射(MapFn&&fn){}
虚T Reduce(ReduceFn&&fn){}
};
int main()
{
基质m;
返回0;
}
一个更灵活的解决方案可以考虑使用<代码> STD::函数< /COD>(例如,<代码> STD::函数< /代码>)用于参数,因为它给调用方更多的灵活性。例如,调用者可以使用普通函数、成员函数、lambda表达式或functor对象。
另一个答案将适用于普通函数指针。但是,使用一点类型擦除,或者对其进行一些修改,也可以使实现合适的操作符()
成员的类的实例实现这种功能
我将为Map()
写出这篇文章。对Reduce()
重复相同的方法类似,这将是一项家庭作业:
#include <cstddef>
template<typename T, size_t N>
class MatBase
{
public:
static constexpr size_t order = N;
using value_type = T;
MatBase() = default;
virtual ~MatBase() = default;
template<typename Arg> void Map(Arg && arg)
{
std::function< value_type(value_type> > f=
[&]
(value_type value)
{
return arg(value);
};
do_map(f);
}
virtual void do_map(std::function< value_type(value_type) > &)=0;
};
#包括
模板
类MatBase
{
公众:
静态constexpr size\u t order=N;
使用值_type=T;
MatBase()=默认值;
virtual~MatBase()=默认值;
模板无效映射(Arg&&Arg)
{
标准::函数<值类型>(值类型>>f=
[&]
(值\类型值)
{
返回arg(值);
};
dou图(f);
}
虚空do_映射(std::function&)=0;
};
另一个答案将适用于普通的、花园式的函数指针。但是使用一点类型擦除,或者对其进行一些修改,也可以使这一方法适用于实现合适的操作符()成员的类实例
我将为Map()
写下这篇文章。对Reduce()
重复同样的方法也是类似的,这将是一个家庭作业:
#include <cstddef>
template<typename T, size_t N>
class MatBase
{
public:
static constexpr size_t order = N;
using value_type = T;
MatBase() = default;
virtual ~MatBase() = default;
template<typename Arg> void Map(Arg && arg)
{
std::function< value_type(value_type> > f=
[&]
(value_type value)
{
return arg(value);
};
do_map(f);
}
virtual void do_map(std::function< value_type(value_type) > &)=0;
};
#包括
模板
类MatBase
{
公众:
静态constexpr size\u t order=N;
使用值_type=T;
MatBase()=默认值;
virtual~MatBase()=默认值;
模板无效映射(Arg&&Arg)
{
标准::函数<值类型>(值类型>>f=
[&]
(值\类型值)
{
返回arg(值);
};
dou图(f);
}
虚空do_映射(std::function&)=0;
};
为什么你不能只写虚拟空位映射(t(&&&)(t))=0;
?t(&&&)(t)和t(*)(t)之间有什么区别?一个是右值引用,一个是指针。我更喜欢@James的版本。为什么你不能只写虚拟空位映射(t(&&&)(t))=0;
?t(&&&&)(t)和t(*)(t)之间有什么区别一个是右值引用,一个是指针。TBH我更喜欢@James的版本。最好使用使用MapFn=T(&&&)(T);
并调用virtualvoidMap(MapFn-fn)=0;
?@Alex我不确定您为什么要使用&
,所以我保留了它们。如果您使用的是普通函数指针,那么我可能会使用虚拟空映射(MapFn-fn)=0;
@Alex注意,您可能希望接受std::function
作为参数类型,因为它更灵活(即,调用方可以使用普通函数、lambda表达式、成员函数)。事实上,此函数将传递给CUDA,因此我在使用std::function时遇到问题,我需要通过复制或移动将其作为模板参数传递。最好使用使用MapFn=T(&&&)(T);
并调用virtual voidMap(MapFn-fn)=0;
?@Alex我不确定您为什么要使用&
,所以我保留了它们。如果您使用的是普通函数指针,那么我可能会使用虚拟空映射(MapFn-fn)=0;
@Alex注意,您可能希望接受std::function
作为参数类型,因为它更灵活(即调用方可以使用普通函数、lambda表达式、成员函数)。事实上,此函数将传递给CUDA,因此我在使用std::function时遇到问题,我需要通过复制或移动将其作为模板参数传递。