Pergunta

Eu quero especializar seguinte função membro:

class foo {
    template<typename T>
    T get() const;
};

Para outro bar classe que depende de modelos bem.

Por exemplo, eu gostaria bar ser std::pair com alguns parâmetros do modelo, algo assim:

template<>
std::pair<T1,T2> foo::get() const
{
    T1 x=...;
    T2 y=...;
    return std::pair<T1,T2>(x,y);
}

Onde T1 e T2 são modelos bem. Como isso pode ser feito? Tanto quanto eu sei que deve ser possível.

Então agora eu posso chamar:

some_foo.get<std::pair<int,double> >();

A resposta completa / final:

template<typename T> struct traits;
class foo {
    template<typename T>
    T get() const
    {
       return traits<T>::get(*this); 
    }
};

template<typename T>
struct traits {
    static T get(foo &f)
    {
        return f.get<T>();
    }
};

template<typename T1,typename T2>
struct traits<std::pair<T1,T2> > {
        static std::pair<T1,T2> get(foo &f)
        {
                T1 x=...;
                T2 y=...;
                return std::make_pair(x,y);
        }
};
Foi útil?

Solução

Você não pode especializar-se parcialmente modelos de função, desculpe, mas essas são as regras. Você pode fazer algo como:

class foo {
   ...
};


template<typename T>
struct getter {
  static T get(const foo& some_foo);
};

template<typename T1, typename T2>
struct getter< std::pair<T1, T2> > {
static std::pair<T1, T2> get(const foo& some_foo) {
    T1 t1 = ...;
    T2 t2 = ...;
    return std::make_pair(t1, t2);
};

e, em seguida, chamá-lo como

getter<std::pair<int, double> >::get(some_foo);

embora. Você pode ter que fazer alguma brincando com friendship ou a visibilidade se get realmente necessário para ser uma função de membro.

Para elaborar a sugestão de SBI:

class foo {
   ...
   template<typename T>
   T get() const;
};

template<typename T>
T foo::get() const
{
  return getter<T>::get(*this);
  /*            ^-- specialization happens here */
}

E agora você está de volta para ser capaz de dizer

std::pair<int,double> p = some_foo.get<std::pair<int, double> >();

Outras dicas

Você precisa sobrecarregar a sua função de membro para o par, como em

template <T, V> std::pair<T, V> foo::get()

No caso geral você precisa ser capaz de ambigüidade entre as várias sobrecargas. No caso disambiguation é fácil, porque par é templated em 2 tipos, enquanto o membro original foi modelada em T somente.

Se em vez você precisava de uma especialização para, por exemplo, std :: vector, que é para um recipiente com um único modelo de parâmetro, você tem que ter cuidado, uma vez dado que pode ser confuso para o compilador para entender se você deseja instanciar a especialização de modelo onde o modelo T é std :: vector ou a especialização para a sobrecarga,

template <T> std::<vector <T> foo::get() const 

A sua sintaxe proposta não pode trabalho desde que você está especializada completamente a função de membro,

template <>,

mas você está deixando de fora dois tipos não especificados, T1 e T2.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top