Domanda

Che la questione, dice. Inoltre, è possibile fare questo in linea?

Ecco un piccolo esempio solo per dare un'idea ...

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void do( const Foo<T> &f ) {
    z = f.z;
  }
  // specialize 'do' for Foo<int>, possible inline?

 private:
  T z;
};
È stato utile?

Soluzione

È possibile ordinare di ottenere questo comportamento, rendendo la funzione di membro di un modello di funzione membro e utilizzando SFINAE (mancata sostituzione non è un errore). Ad esempio:

template <typename U>
typename std::enable_if<!std::is_integral<U>::value && 
                        std::is_same<T, U>::value, void>::type
f(const Foo<U>& x)
{
}

template <typename U>
typename std::enable_if<std::is_integral<U>::value && 
                        std::is_same<T, U>::value, void>::type
f(const Foo<U>& x)
{
}

La prova tratto tipo is_integral se U è di tipo intero. Se non lo è, il primo è istanziato; se lo è, il secondo viene istanziata.

I test tratto tipo is_same a garantire T e U sono dello stesso tipo. Questo viene utilizzato per garantire che il modello di funzione di membro non viene creata un'istanza per qualsiasi tipo diverso da Foo<T>.

In questo esempio fa uso della libreria <type_traits> C ++ 0x; Boost ha anche una libreria di tipi tratti che è possibile utilizzare, che funziona in gran parte la stessa.

Altri suggerimenti

Non c'è bisogno di fare nulla di complicato. Basta usare il sovraccarico e la delega. Si noti che non possiamo aggiungere un sovraccarico int, perché quando T risulta essere int troppo, questo sarebbe un sovraccarico non valida (due funzioni con la stessa firma)

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void doIt(const Foo<T> &f ) {
    doItImpl(f);
  }

 private:
  template<typename U>
  void doItImpl(const Foo<U> &f) {
    z = f.z;
  }

  void doItImpl(const Foo<int> &f) {
    /* ... */
  }

 private:
  T z;
};

In alternativa, per questo caso, si può fare questo per specializzazione

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void doIt(const Foo<T> &f ) {
    z = f.z;
  }

 private:
  T z;
};

template<>
inline void Foo<int>::doIt(const Foo<int> &f) {
  /* ... */
}

Utilizzando la specializzazione in questo modo è possibile solo se tutti gli argomenti di template sono fisse. In altre parole, parzialmente specializzata la funzione membro non è possibile.

Puoi provare a fare qualcosa di simile (non prova, potrebbe non funzionare):

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  template<typename Ty = T>
  void do( const Foo<T> &f ) {
    z = f.z;
  }

  template<>
  void do<int>( const Foo<T> &f ) {
    //specialized code
  }

 private:
  T z;
};
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top