Вызов функции специализированного класса шаблона из специализированной функции класса шаблона - PullRequest
14 голосов
/ 06 января 2011

Можно ли вызвать функцию, определенную в неспециализированном шаблонном классе, из специализированного шаблонного класса? Вот пример того, что я пытаюсь сделать:

template <typename T>
struct Convert
{
 static inline void toString(unsigned num, unsigned places, std::string& str) { ... }
};

template <>
struct Convert<int8_t>
{
 static inline void toString(unsigned num, std::string& str)
 {
   Convert<int8_t>::toString(num, digitis(num), str);
 }
};

GCC жалуется на то, что не может видеть функцию неспециализированного класса; то есть, я думаю, это выглядит только в пределах специализированного класса.

Есть мысли?

EDIT

Вот более конкретный пример из моего кода (с возможным решением):

struct NonSpecial { };

template <typename T>
class Convert
{

        template <typename R>
        static inline R fromString(const register char *str, const unsigned str_len)
        {   
            R result = 0;
            //convert str to R
            return result;
        }

        friend class Convert<int8_t>;
        friend class Convert<uint8_t>;
}

template <>
struct Convert<int8_t>     
{
    static inline int8_t fromString(const register char* str, const unsigned str_len = 4)
    {
        Convert<NonSpecial>::fromString<int8_t>(str, str_len);    
    }
};

template <>
struct Convert<uint8_t>     
{
    static inline uint8_t fromString(const register char* str, const unsigned str_len = 3)
    {
        Convert<NonSpecial>::fromString<uint8_t>(str, str_len);    
    }
};

У меня есть другие функции - toString (), countDigits () и т. Д. Я выбрал этот подход, чтобы я мог сохранять одинаковые имена функций для каждого типа (т. Е. Не нужно toStringU32 (), toString32 и т. Д.). Я рассмотрел специализацию шаблонов, но не верю, что это возможно.

1 Ответ

10 голосов
/ 06 января 2011

Как правило, это невозможно.

Существуют разные возможные решения, но они «обманывают». Первый заключается в том, чтобы поднять действующую логику по умолчанию в другую функцию, которая не специализирована. Теперь вы можете вызывать эту функцию из обеих toString реализаций.

Второй вариант предполагает наследование от неспециализированного класса и передачу специального тега в качестве аргумента шаблона:

struct BaseClassTag { };

template <>
struct Convert<int8_t> : public Convert<BaseClassTag>
{
 typedef Convert<BaseClassTag> TBase;
 static inline void toString(unsigned num, std::string& str)
 {
   TBase::toString(num, digitis(num), str);
 }
};
...