Como encaminhar declarar uma classe de modelo C ++?


99

Dada uma classe de modelo como a seguinte:

template<typename Type, typename IDType=typename Type::IDType>
class Mappings
{
public:
    ...
    Type valueFor(const IDType& id) { // return value }
    ...
};

Como alguém pode declarar essa classe em um arquivo de cabeçalho?

Respostas:


103

É assim que você faria:

template<typename Type, typename IDType=typename Type::IDType>
class Mappings;

template<typename Type, typename IDType>
class Mappings
{
public:
    ...
    Type valueFor(const IDType& id) { // return value }
    ...
};

Observe que o padrão está na declaração de encaminhamento e não na definição real.


É possível declarar progressivamente uma classe que tem seus padrões listados em sua definição. Veja minha resposta.
— Elliott

Discordo. O padrão diz: "Um parâmetro-modelo não deve receber argumentos padrão por duas declarações diferentes no mesmo escopo" . E não encontrei nada sobre padrões apenas na primeira declaração. Além disso, o código com a declaração de encaminhamento e padrões na definição é compilado e executado com êxito. Tem certeza do que está reivindicando? Você pode fornecer uma cotação do padrão?
— olek stolar

@Elliott Parece que é verdade. O padrão [17.1.9] diz: "Um argumento-modelo padrão pode ser especificado em uma declaração de modelo." Não deve ser, mas pode ser. Portanto, não entendo por que outras respostas afirmam que deveria estar na primeira declaração.
— olek stolar

E parece ser muito mais conveniente ter padrões na definição.
— olek stolar

8

Você pode declarar argumentos padrão para um modelo apenas para a primeira declaração do modelo. Se você deseja permitir que os usuários declarem um modelo de classe, você deve fornecer um cabeçalho de encaminhamento. Se você deseja declarar o template de classe de outra pessoa usando padrões, você está sem sorte!


É possível declarar progressivamente uma classe que tem seus padrões listados em sua definição. Veja minha resposta.
— Elliott

Discordo. O padrão diz: "Um parâmetro-modelo não deve receber argumentos padrão por duas declarações diferentes no mesmo escopo" . E não encontrei nada sobre padrões apenas na primeira declaração. Além disso, o código com a declaração de encaminhamento e padrões na definição é compilado e executado com êxito. Tem certeza do que está reivindicando? Você pode fornecer uma cotação do padrão?
— olek stolar

3

Você pode declarar uma classe modelada cuja definição declara os argumentos padrão, mas sempre que fizer referência à classe, deverá incluir todos os seus argumentos até que a definição seja introduzida.

por exemplo. Vamos usar std::vectorsem incluí-lo (o segundo argumento de std::vectoré definido com um padrão):

namespace std
{
    template<typename, typename>
    class vector;
}

#include <iostream>

template <typename S, typename T>
void Foo (const std::vector<S,T> & vector)
{
    std::cout << "do vector stuff, eg., display size = "
        << vector.size() << std::endl;
}

template <typename T>
void Foo (const T & t)
{
    std::cout << "do non-vector stuff..." << std::endl;
}

Podemos então usá-lo sem incluir o vetor, por exemplo:

int main()
{
    Foo(3);
}

E podemos usá-lo com std::vector , por exemplo:

#include <vector>

// Now the compiler understands how to handle
// std::vector with one argument
// (making use of its default argument)

int main()
{
    Foo(std::vector<int>(3));
}

Não verifiquei os padrões, mas isso funciona em clang/ gcccom -std=c++98até -std=c++17, então, se não for oficialmente um padrão, parece que não é oficial.


Talvez você esqueça os colchetes angulares vazios Foo<> foo;.
— olek stolar de

@ OleksijPlotnyc'kyj você está certo. Obrigado. Excluí essa adição.
— Elliott
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.