如何将模板类中的模板函数转换为功能指针

How to turn a template function in a template class to a function pointer

本文关键字:转换 指针 函数 功能      更新时间:2023-10-16

我正在尝试将混凝土工厂变成模板工厂类。以下是我写的;我正在使用G (GCC)4.8.5。

G 抱怨error: no matches converting function ‘create’ to type ‘using create_t = class Base* (*)() {aka class Base* (*)()}’。句子create_t pf = create<S>;失败了,但我不知道它是什么。

#include<iostream>
#include<type_traits>
class Base {
public:
    virtual ~Base() {}; 
    virtual void print() {
        std::cout << "In Base." << std::endl;
    }   
};
class Derived: public Base {
public:
    void print() {
        std::cout << "In Derived." << std::endl;
    }   
};

template<typename T>
class Factory {
public:
    using create_t = T* (*) (); 
    template<typename S>
    T* create() {
        static_assert(std::is_base_of<T, S>::value, "S must be a derived of T.");
        return new S();
    }   
    template<typename S>
    void test() {
        create_t pf = create<S>;
        T * pt = pf();
        pt->print();                                                                                                                                                                                              
        delete pt;
    }   
};
int main() {
    Factory<Base> base_factory;
    base_factory.test<Derived>();
    return 0;
}

您错过了static关键字:

template<typename S>
static T* create() {
    static_assert(std::is_base_of<T, S>::value, "S must be a derived of T.");
    return new S();
} 

演示

因为没有 static,它是一个非静态成员函数,其类型为 T* (Factory::*) ();如果您确实需要它作为非静态成员函数:

using self = Factory;
using create_t = T* (self::*) (); 
template<typename S>
T* create() {
    static_assert(std::is_base_of<T, S>::value, "S must be a derived of T.");
    return new S();
}   
template<typename S>
void test() {
    create_t pf = &self::create<S>;
    T * pt = (this->*pf)();
    pt->print();                                                                                                                                                                                              
    delete pt;
}  

demo