简体   繁体   中英

Template specialization base class function template missing

Consider the following:

#include <iostream>
#include <string>

/**
 * Provides base functionality for any property.
 */
struct property_base
{
    virtual std::string to_string() const = 0;
    
protected:
    void notify() { std::cout << "notifying!" << std::endl; }    
};

/**
 * Generic property implementation template.
 */
template<typename T>
struct property_impl :
    property_base
{
    T data;
    
    property_impl<T>& operator=(const T& t)
    {
        this->data = t;
        this->notify();
        return *this;
    }
};

/**
 * Generic property template.
 */
template<typename T>
struct property :
    property_impl<T>
{
};

/**
 * 'int' property specialization
 */
template<>
struct property<int> :
    property_impl<int>
{
    std::string to_string() const { return std::to_string(data); }
};

/**
 * `std::string` property specialization
 */
template<>
struct property<std::string> :
    property_impl<std::string>
{
    std::string to_string() const { return data; }  
};

int main()
{
    property<int> x;
    property<std::string> str;
    
    x = 42;
    str = "Hello World!";
    
    return 0;
}

When compiling this, the compiler complains about not finding a match for operator= with operand types property<int> and int . As I understand the problem is that I'm calling property<int>::operator=(int) which does not exist. Instead, I only have property_impl<int>::operator(int) defined.

Is there a way of making this work without requiring each property<T> template specialization to explicitly implement the operator=() ? The implementation of operator= will be the same for all specialization so I'm looking for a way of not requiring an explicitly implemented operator= for all future property<T> specializations.

Coliru link to thinker: http://coliru.stacked-crooked.com/a/1db9165e4f78ffa4

Very few things in C++ happen automatically. Fortunately, in this case you don't have to write a lot of additional code, only add a using declaration to each subclass:

/**
 * 'int' property specialization
 */
template<>
struct property<int> :
    property_impl<int>
{
    using property_impl<int>::operator=;
    std::string to_string() const { return std::to_string(data); }
};

/**
 * `std::string` property specialization
 */
template<>
struct property<std::string> :
    property_impl<std::string>
{
    using property_impl<std::string>::operator=;
    std::string to_string() const { return data; }
};

You will have to explicitly add the using declaration to this subclass, but that's still better than having to copy/paste the same operator= in each one of them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM