Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++_Templates_Overloading_Variadic Templates_Partial Specialization - Fatal编程技术网

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