C++ 使用可变参数专门化和/或重载成员函数模板
尝试解析类成员的重载解析:静态函数模板重载-部分专门化 我目前有一个类被声明/定义为: 注意:我使用的C++ 使用可变参数专门化和/或重载成员函数模板,c++,templates,overloading,variadic-templates,partial-specialization,C++,Templates,Overloading,Variadic Templates,Partial Specialization,尝试解析类成员的重载解析:静态函数模板重载-部分专门化 我目前有一个类被声明/定义为: 注意:我使用的参数a、参数b、参数c等与实际声明/定义没有直接关系。这些可以是传递到函数中的任意类型,例如:它可以是inta,enum b,char c。我只是用它来显示声明的模式,但是所有不同的引擎都使用相同的3个不同的参数 SomeEngine.h #ifndef SOME_ENGINE_H #define SOME_ENGINE_H class SomeEngine { public: Som
参数a
、参数b
、参数c
等与实际声明/定义没有直接关系。这些可以是传递到函数中的任意类型,例如:它可以是inta
,enum b
,char c
。我只是用它来显示声明的模式,但是所有不同的引擎都使用相同的3个不同的参数
SomeEngine.h
#ifndef SOME_ENGINE_H
#define SOME_ENGINE_H
class SomeEngine {
public:
SomeEngine() = delete;
static engineA& getEngineA( Param a, Param b, Param c );
static engineB& getEngineB( Param a, Param b, Param c );
// ... more static functions to return other engines
template<class Engine>
static Engine& getEngine( Param a, Param b, Param c );
};
// Another class
// function template that uses both classes above
#endif // SOME_ENGINE_H
除此处显示的功能不完整外,上述功能正常工作。它依赖于另一个类。另一个类本身具有与上面一个类似的模式;它有一个已删除的默认构造函数,以及一组用于返回不同类型对象的静态方法;然而,在第二个类中,几乎所有的静态方法本身都是函数模板,一些具有重载版本,而另一些具有多个模板参数。它也在上面相同的头文件中声明。它看起来像这样:
class SomeOther {
public:
SomeOther() = delete;
template<class IntType = int>
static otherA<IntType>& getOtherA( IntType a, IntType b );
template<class RealType = double>
static otherB<RealType>& getOtherB( RealType a, RealType B );
template<class IntType = int>
static otherC<IntType>& getOtherC( IntType a );
template<class RealType = double>
static otherD<RealType>& getOtherD( RealType a );
template<class IntType = int>
static otherE<IntType>& getOtherE();
template<class IntType = int>
static otherE<IntType>& getOtherE( IntType a, IntType b );
template<class IntType = int>
static otherE<IntType>& getOtherE( std::initializer_list<double> a );
template<class IntType = int, class X>
static otherE<IntType>& getOtherE( std::size_t a, double b, double c, X x );
};
template< typename Type,
template<typename, class...> class Other,
class... OtherParams,
class... FuncParams>
static Other<Type, OtherParams...>& getOther( FuncParams... params );
class Tmp
{
public:
template<class A, class B>
void bar(A a, B b) {}
};
template<class A>
void Tmp::bar<A, int>(A a, int b) {}
然后我在上面展示的功能还没有完成,我在添加对第二类的支持时尝试了这个功能:
template< class Engine,
typename Type,
template<typename, class...> class Other,
class... OtherParams,
class... FuncParams>
Type generate( Param a, Param b, Param c, FuncParams... params ) {
static Type retVal = 0;
static Engine engine = SomeEngine::getEngine<Engine>( a, b, c );
static Other<Type, OtherParams...> other = SomeOther::getOther<Type, Other<Type, OtherParams...>> ( params... );
retVal = other( engine );
return retVal;
}
模板
类型生成(参数a、参数b、参数c、函数参数…参数){
静态类型retVal=0;
静态引擎Engine=SomeEngine::getEngine(a、b、c);
static Other=SomeOther::getOther(参数…);
retVal=其他(发动机);
返回返回;
}
这就是我如何使用上面的第二个类。下面是我尝试在相应的cpp文件中专门化两个getOther()函数的尝试
template<typename Type,
template<typename, class...> class Other,
class... OtherParams,
class... FuncParams>
otherA<Type>& SomeOther::getOther( FP... params ) {
return getOtherA( params... );
}
template<typename Type,
template<typename, class...> class Other,
class... OtherParams,
class... FuncParams>
otherB<Type>& SomeOther::getOther( FP... params ) {
return getOtherB( params... );
}
模板
otherA&SomeOther::getOther(FP…params){
返回getOtherA(参数…);
}
模板
otherB和SomeOther::getOther(FP…params){
返回getOtherB(参数…);
}
这不会编译它会抱怨函数定义与现有声明不匹配。我甚至试着在头文件中写一个重载,我不断地得到同样的错误。我不知道这是否是语法错误。我已经试着在这里列出了很多东西,我到处寻找类似的东西,但似乎找不到任何相关的东西
我想知道这样的事情是否可以做到;如果是这样的话,为了使它至少能够编译和构建,上面需要修改什么;所以我可以在运行时开始测试它;然后继续添加其他现有类型
我想尝试和第二类保持同样的设计模式。我的独立函数模板是将被调用的函数,取决于它的模板参数;它应该知道调用哪个引擎-其他类型 在第二种情况下,实际上您并不是在试图部分地专门化
getOther
。部分专门化应该这样写:
class SomeOther {
public:
SomeOther() = delete;
template<class IntType = int>
static otherA<IntType>& getOtherA( IntType a, IntType b );
template<class RealType = double>
static otherB<RealType>& getOtherB( RealType a, RealType B );
template<class IntType = int>
static otherC<IntType>& getOtherC( IntType a );
template<class RealType = double>
static otherD<RealType>& getOtherD( RealType a );
template<class IntType = int>
static otherE<IntType>& getOtherE();
template<class IntType = int>
static otherE<IntType>& getOtherE( IntType a, IntType b );
template<class IntType = int>
static otherE<IntType>& getOtherE( std::initializer_list<double> a );
template<class IntType = int, class X>
static otherE<IntType>& getOtherE( std::size_t a, double b, double c, X x );
};
template< typename Type,
template<typename, class...> class Other,
class... OtherParams,
class... FuncParams>
static Other<Type, OtherParams...>& getOther( FuncParams... params );
class Tmp
{
public:
template<class A, class B>
void bar(A a, B b) {}
};
template<class A>
void Tmp::bar<A, int>(A a, int b) {}
您似乎在使用
Other
有时作为模板,有时作为类型。这不太好。@Aschepper这就是我在声明/定义方面遇到的问题。我正试图编写一个通用函数模板,从第二个类中选择合适的函数模板;但是,其中一些函数模板可能有多个模板参数,并且其参数列表会有所不同。使用引擎很容易,因为它们都不是模板,并且都有相同的3个参数;但例如:otherA a
可以是一种类型,而otherB b
可以是一种类型。其中a的
构造函数可能有(inta,intb)
,而b的
构造函数可能有(a1,a2,b1)
。我需要解析将调用这些方法的泛型函数模板的所有参数类型。@aschepper我已将类的名称从Other
更改为SomeOther
,以便函数声明与类Other
的模板参数参数列表不会混淆或冲突;在我的实际代码中,它们不是相同的名称;但问题是:另一个我将返回的是
头文件中发现的不同类型的发行版。这些类已经声明。我只想funnel
返回相应分发版所需的类型。您可以看到,我使用静态函数以独立的名称返回每个分发,例如std::uniform\u int\u distribution&Bar::getUniformIntDistriubtion(IntType a,IntType b)代码>所以我不想重写类。我想要一个getDistriubtion(参数…)代码>函数。@FrancisCugler对不起,我没有真正理解要点。您不需要重写otherA
/otherB
/etc…,只需更改Bar
Bar
是您自己的实现,对吗?Bar本身是一个非模板类,它只有静态方法来获取不同类型的发行版。每个静态方法本身都已经是函数模板。现在,我正试图编写一个函数模板,根据指定的发行版的函数模板参数列表来获得特定的发行版,然后该发行版将使用什么类型。这个老问题可能会对您有所帮助,因为它实际上有我的类(至少是类的一部分)@FrancisCugler当otherA
是std::uniform\u int\u distribution
时,我仍然没有看到任何区别。你以前做的是专门研究
template <class T>
class otherA
{
T t;
public:
otherA(T t) : t(t) {}
void WhoAmI() { cout << "I'm OtherA" << endl; }
T getValue() { return t; }
};
template <class T, class X>
class otherE
{
T t;
public:
otherE(T t) : t(t) {}
void WhoAmI() { cout << "I'm OtherE" << endl; }
T getValue() { return t; }
};
class SomeOther {
public:
SomeOther() = delete;
template<class IntType = int>
static otherA<IntType>& getOtherA(IntType a, IntType b)
{
static otherA<IntType> A(a);
return A;
}
template<class IntType = int, class X>
static otherE<IntType, X>& getOtherE(IntType a, double b, double c, X x)
{
static otherE<IntType, X> E(a);
return E;
}
template<template<typename, class...> class Other,
class Type,
class... OtherParams,
class... FuncParams>
static Other<Type, OtherParams...>& getOther(FuncParams... params)
{
return getOther<Type, OtherParams...>(params...);
}
private:
/// Function Overloading
template<class T,
class... FuncParams>
static otherA<T>& getOther(FuncParams... params)
{
return getOtherA<T>(params...);
}
template<class T,
class X,
class... FuncParams>
static otherE<T, X>& getOther(FuncParams... params)
{
return getOtherE<T, X>(params...);
}
};
template<
class Type,
template<typename, class...> class Other,
class... OtherParams,
class... FuncParams>
Type test(FuncParams... params) {
static Other<Type, OtherParams...>& other = SomeOther::getOther<Other, Type, OtherParams...>(params...);
other.WhoAmI();
return other.getValue();
}
class foo{};
int main()
{
int AValue = test<int, otherA>(1, 2);
cout << "AValue: " << AValue << endl;
int EValue = test<int, otherE, foo>(3, 2.1, 2.2, foo());
cout << "EValue: " << EValue << endl;
return 0;
}
I'm OtherA
AValue: 1
I'm OtherE
EValue: 3