代码之家  ›  专栏  ›  技术社区  ›  Sturm

如果启用模板专用化

  •  2
  • Sturm  · 技术社区  · 6 年前

    我正试图以这种方式专门化模板:

    class PropertyBase
    {
    public:
        SfPropertyBase(string name)
        {
            Name = name;
        }
    
        virtual ~SfPropertyBase() {}
    
        string Name;
    
        virtual bool FromString(Object* obj, string str) = 0;
    
    };
    
    
    template< typename T>
    class Property : public SfPropertyBase
    {
    public:
        Property(string name) : SfPropertyBase(name)
        {
            //specific to Property stuff
        }
    
    
    
        template<typename U = T>
        typename std::enable_if<(std::is_class<U>::value && std::is_pointer<U>::value), bool>::type
        FromString(Object* obj, string str)
        {
            //do something
            return true;
        }
    
        template<typename U = T>
        typename std::enable_if<!std::is_class<U>::value || !std::is_pointer<U>::value), bool>::type
        FromString(Object* obj, string str)
        {
            //do something
            return true;
        }
    }
    

    然后,当我尝试初始化此类的实例时:

     auto prop = new Property<int>("IntProperty");
    

    我明白了 invalid new-expression of abstract class type Property<int> . 我知道在 PropertyBase ,但我也为 Property ,其中 T 是一个类而不是。

    怎么回事,怎么解决?

    注:我想达到的是专业化 FromString 如果T是一个类/指针和所有其他情况。

    2 回复  |  直到 6 年前
        1
  •  5
  •   songyuanyao    6 年前

    两者 FromString 在里面 Property 是函数模板,它们不能 覆盖 非模板 virtual 基类的函数。(实际上,函数模板不能 virtual functions ).

    您可以添加另一个非模板 从字符串 在里面 财产 ;并且您可以使用关键字确保覆盖 orverride . 例如

    bool FromString(Object* obj, string str) override {
        return FromString<>(obj, str);
    }
    

    LIVE

        2
  •  4
  •   StoryTeller - Unslander Monica    6 年前

    函数模板不能用作非模板虚拟函数的重写器。函数模板不是函数,而是创建函数的配方 按需 打电话的时候。

    代码必须调用 FromString 直接在派生类对象上运行SFINAE。如果要根据模板参数类型提供不同的重写器,一种方法是通过中间基。

    template<typename T, typename = void>
    struct FromStringProvider;
    
    template<typename T>
    struct FromStringProvider<T, typename std::enable_if<(std::is_class<U>::value && std::is_pointer<U>::value)>::type> : SfPropertyBase {
        bool FromString(Object* obj, string str) override
        {
            //do something
            return true;
        }
    };
    

    如果需要访问派生类,则可以使用基于CRTP的方法。只需将派生类作为额外参数传递,并依赖其静态接口访问所需的部分。

    如果在相同的条件下有一组虚拟函数,这种替代方法尤其有用。