18

特殊化されていないテンプレート クラスで定義された関数を、特殊化されたテンプレート クラスから呼び出すことは可能ですか? これが私が試みているものの例です:

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 は、特殊化されていないクラス関数を認識できないと不平を言っています。つまり、特殊なクラス内でのみ見えると思います。

何かご意見は?

編集

これは私のコードのより具体的な例です(可能な解決策があります):

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 などは必要ありません)。テンプレートの特殊化を検討しましたが、これが可能だとは思いません。

4

1 に答える 1

14

一般に、これは不可能です。

さまざまな解決策がありますが、それらは「ごまかす」ものです。1 つ目は、実際のデフォルト ロジックを特殊化されていない別の関数に引き上げることです。toStringこれで、両方の実装からこの関数を呼び出すことができます。

2 番目の方法では、特殊化されていないクラスから継承し、テンプレート引数として特殊なタグを渡します。

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);
 }
};
于 2011-01-06T17:06:53.393 に答える