2

template関数がclass呼び出された場合にのみインスタンス化されるという間違った認識がありました。以下の簡単なコードを参照してください。

template<typename T>
struct A
{
  T *p; 
  T& operator * () { return *p; }
};

int main ()
{
  A<int> ai;   // ok
  int i = *ai;  // works fine
  A<void> av;  // compiler complains even "*av" is not called
}

を宣言している間A<void>、コンパイラは次のようにエラーを出します:

error: forming reference to void

void以下のように、テンプレートの外側に関数を特化しようとしました。

template<>
void A<void>::operator * () {}

しかし、それは役に立たず、次のようなエラーが発生します:

error: no member function ‘operator*’ declared in ‘A<void>’

これを C++03 で修正する方法はありますか?

4

3 に答える 3

5

どうですか

template < typename T >
struct ReferenceOrVoid
{ typedef T& Value; };

template < >
struct ReferenceOrVoid < void >
{ typedef void Value; };

template<typename T>
struct A
{
    T *p; 
    typename ReferenceOrVoid < T > :: Value
    operator * () { return *p; }
};

もちろん、 が の場合にどのように動作したいかによって異なりAます。もちろん、構造体全体を に特化することもできます。TvoidAvoid

于 2012-10-06T18:21:25.417 に答える
3

関数に別の戻り値の型を与えれば十分だと思いますvoid

template <typename T>
struct is _void {
    enum { value = false };
};
template <>
struct is_void<> {
    enum { value = true };
};

struct A {
    ...
    typename enable_if<!is_void<T::value>, T&>::type
    operator*() {
        ...
    }
};

署名は引き続きチェックされる可能性があるため、条件付きタイプを使用する必要がある場合がありvoidますvoid

template <bool, typename T1, typename>
struct conditional {
    typedef T1 type;
};
template <typename T1, typename T2>
struct conditional<false, T1, T2> {
    typedef T2 type;
};
于 2012-10-06T18:19:34.050 に答える
3

関数の署名はインスタンス化されますが、関数の本体はインスタンス化されません。T関数を使用しているかどうかに関係なく、クラス定義全体で置き換えられます。これに注意してください:

template<typename T>
struct A
{
  T *p; 
  T *operator * () { return p->aklsdjlkasjd(); }
};

int main ()
{
  A<void> av;  
}

を使用していないため、コンパイルされますoperator*

于 2012-10-06T18:20:05.537 に答える