【发布时间】:2018-03-19 23:34:46
【问题描述】:
尝试解决类成员的重载决议:静态函数模板重载 - 部分特化。
我目前有一个这样声明/定义的类:
注意:我对@987654321@、Param b、Param c等的使用与实际的声明/定义没有直接关系。这些可以是传递给函数的任意类型,例如:它可以是int a、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
SomeEngine.cpp
#include "SomeEngine.h"
template<>
EngineA& SomeEngine::getEngine( Param a, Param b, Param c ) {
return getEngineA( a, b, c );
}
template<>
EngineB& SomeEngine::getEngine( Param a, Param b, Param c ) {
return getEngineB( a, b, c );
}
上面的函数模板设计模式,我能够使用单个通用 getEngine() 调用来专门化类以返回适当的引擎类型,编译并且工作正常。我有一个非类成员函数模板,它采用class Engine 作为其模板参数之一...这是在上面任何类之外的同一个标题中定义的,并且在它将使用的前两个类之后。
template<class Engine, typename T>
T generateVal( Param a, Param b, Param c ) {
static T retVal = 0;
static Engine engine = SomeEngine::getEngine<Engine>( a, b , c );
}
除了这里显示的功能不完整之外,上述工作。它依赖于另一个类。另一个类本身具有与上述类似的模式;它有一个已删除的默认构造函数,以及一堆返回不同类型对象的静态方法;但是在第二类中,几乎所有的静态方法本身都是函数模板,有些具有重载版本,而另一些则具有多个模板参数。它也在上面的同一个头文件中声明。它看起来像这样:
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 );
};
我正在尝试对上面的第二个类做类似的事情,以获得一个通用函数模板,这样我就可以将模板参数 class Other 传递给它,除了 class Other 取决于它自己的模板参数和内部函数调用可能有不同数量的参数。
这让我开始使用可变参数模板来声明这个类的函数。
我曾尝试过这样的事情:
template< typename Type,
template<typename, class...> class Other,
class... OtherParams,
class... FuncParams>
static Other<Type, OtherParams...>& getOther( FuncParams... params );
然后我上面显示的功能不完整,我在添加对第二类的支持时尝试了这个:
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;
}
这就是我将如何使用上面的第二类。这是我尝试在相应的 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... );
}
这不会编译它抱怨函数定义与现有声明不匹配。我什至试图在头文件中写一个重载,但我一直收到同样的错误。我不知道这是否是语法错误。我已经尝试了很多东西来在这里列出,我已经在整个地方搜索了类似的东西,但似乎找不到任何相关的东西。
我想知道这样的事情是否可以做到;如果是这样,上面需要更改什么才能至少编译和构建;所以我可以在运行时开始测试它;然后继续添加其他现有类型。
我想尝试保持第一类与第二类相同的设计模式。我的独立函数模板是将被调用的函数,取决于它的模板参数;它应该知道要调用哪个引擎-其他类型。
【问题讨论】:
-
您似乎将
Other有时用作模板,有时用作类型。那不会很顺利。 -
@aschepler 这就是我在声明/定义方面遇到的麻烦。
-
我正在尝试编写一个通用函数模板,它将从第二类中选择适当的函数模板;然而,其中一些函数模板可能有多个模板参数,并且它们的参数列表各不相同。使用引擎很容易,因为它们都不是模板,并且它们都具有相同的 3 个参数。
-
到底Other应该是一个类对象;但例如:
otherA<int> a可能是一种类型,而otherB<double, class A, class B> b。其中a's构造函数可能有(int a, int b)和b's构造函数可能有( A a1, A a2, B b1 )。我需要为调用这些方法的通用函数模板解析所有参数类型。 -
@aschepler 我已经将类的名称从
Other更改为SomeOther,这样带有class Other模板参数参数列表的函数声明就不会让您感到困惑或冲突;在我的实际代码中,它们的名称不同。
标签: c++ templates overloading variadic-templates partial-specialization