La specializzazione parziale di un modello di classe nella classe derivata influisce sulla classe base

StackOverflow https://stackoverflow.com/questions/1413158

Domanda

Ho una metafunzione:

struct METAFUNCION
{
  template<class T>
  struct apply
  {
    typedef T type;
  };
};

Quindi definisco un aiuto:

template<class T1, class T2>
struct HELPER
{
};

E poi ho una seconda metafunzione che deriva dalla METAFUNCTION sopra e che definisce la specializzazione parziale di struct struct:

struct METAFUNCION2 : METAFUNCION
{
  template<class T1, class T2>
  struct apply<HELPER<T1, T2> > : METAFUNCION::apply<T2>
  {
  };
};

Finora, tutto bene - il codice viene compilato sotto g ++ 4.3.2. Quindi l'ho usato come di seguito:

#include <typeinfo>
#include <string>
#include <cstdlib>
#include <cxxabi.h>

template<typename T>
struct type_info2
{
  static std::string name()
  {
    char *p = abi::__cxa_demangle(typeid(T).name(), 0, 0, 0);
    std::string r(p);
    free(p);
    return(r);
  }
};

#include <boost/mpl/apply.hpp>
#include <iostream>

int main()
{
  std::cout <<
    type_info2<boost::mpl::apply<METAFUNCION, int>::type>::name() <<
    std::endl;
  std::cout <<
    type_info2<boost::mpl::apply<METAFUNCION, HELPER<float, double> >::type>::name() <<
    std::endl;
  std::cout <<
    type_info2<boost::mpl::apply<METAFUNCION2, HELPER<float, double> >::type>::name() <<
    std::endl;
  return(0);
}

L'output:

int
double
double

Mi ha sorpreso un po 'come mi aspettavo:

int
HELPER<float, double>
double

Ora, so che il codice come sopra non viene compilato in Microsoft Visual C ++ 2008 (non ricordo il messaggio ma era qualcosa sulla falsariga che non posso specializzare applicare struct all'interno di METAFUNCTION2 struct).

Quindi la mia domanda è: questo comportamento g ++ è conforme allo standard? Ho la netta sensazione che ci sia qualcosa di sbagliato qui, ma non ne sono sicuro al 100%.


Per i curiosi - Ho il comportamento come mi aspettavo quando ridefinisco METAFUNCTION2 in questo modo:

struct METAFUNCION2 : METAFUNCION
{
  template<class T>
  struct apply : METAFUNCION::apply<T>
  {
  };
  template<class T1, class T2>
  struct apply<HELPER<T1, T2> > : METAFUNCION::apply<T2>
  {
  };
};
È stato utile?

Soluzione

Il seguente codice è illegale:

struct METAFUNCION2 : METAFUNCION
{
  template<class T1, class T2>
  struct apply<HELPER<T1, T2> > : METAFUNCION::apply<T2>
  {
  };
};

Secondo la norma C ++ 14.7.3 / 3:

  

Una dichiarazione di un modello di funzione o di un modello di classe esplicitamente specializzato deve essere inclusa nel campo di applicazione   punto di dichiarazione di una specializzazione esplicita.

MODIFICA: Secondo Numero principale 727 questa restrizione non si applica alle specializzazioni parziali dei modelli di membri.

Altri suggerimenti

Quindi ho archiviato un bug su gcc

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top