Jak przesłać dalej deklarację klasy szablonu C ++?

105

Biorąc pod uwagę klasę szablonu, taką jak poniższa:

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

Jak ktoś może przekazać dalej tę klasę w pliku nagłówkowym?

Tron Thomas
źródło

Odpowiedzi:

108

Oto jak byś to zrobił:

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 }
    ...
};

Zauważ, że wartość domyślna znajduje się w deklaracji forward, a nie w rzeczywistej definicji.

Pubby
źródło
Możliwe jest zadeklarowanie klasy, której wartości domyślne są wymienione w definicji. Zobacz moją odpowiedź.
Elliott
Nie zgadzam się. Norma mówi: „Szablon-parametr nie powinien otrzymywać domyślnych argumentów przez dwie różne deklaracje w tym samym zakresie” . I tylko w pierwszej deklaracji nie znalazłem nic na temat uchybień. Również kod z deklaracją forward i wartościami domyślnymi w definicji pomyślnie kompiluje się i uruchamia. Czy jesteś pewien, czego żądasz? Czy możesz podać wycenę ze standardu?
oleksijp
@Elliott Wygląda na to, że to prawda. Standard [17.1.9] mówi: „Domyślny argument szablonu może być określony w deklaracji szablonu”. Nie musi, ale może być. Dlatego nie rozumiem, dlaczego inne odpowiedzi mówią, że powinno to być w pierwszej deklaracji.
oleksijp
I wydaje się, że znacznie wygodniej jest mieć wartości domyślne w definicji.
oleksijp
8

Możesz zadeklarować domyślne argumenty dla szablonu tylko dla pierwszej deklaracji szablonu. Jeśli chcesz, aby użytkownicy mogli przekazywać dalej deklarowanie szablonu klasy, należy podać nagłówek przekazywania. Jeśli chcesz przekazać dalej zadeklarować szablon klasy innej osoby przy użyciu wartości domyślnych, nie masz szczęścia!

Dietmar Kühl
źródło
Możliwe jest zadeklarowanie klasy, której wartości domyślne są wymienione w definicji. Zobacz moją odpowiedź.
Elliott
Nie zgadzam się. Norma mówi: „Szablon-parametr nie powinien otrzymywać domyślnych argumentów przez dwie różne deklaracje w tym samym zakresie” . I tylko w pierwszej deklaracji nie znalazłem nic na temat uchybień. Również kod z deklaracją forward i wartościami domyślnymi w definicji pomyślnie kompiluje się i uruchamia. Czy jesteś pewien, czego żądasz? Czy możesz podać wycenę ze standardu?
oleksijp
4

Państwo może zadeklarować klasę na matrycy którego definicja wskazuje argumenty domyślne, ale za każdym razem można odwołać klasę musi obejmować wszystkie swoje argumenty, aż zostanie wprowadzona definicja.

na przykład. Użyjmy std::vectorbez dołączania go (drugi argument std::vectorjest zdefiniowany domyślnie):

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;
}

Możemy wtedy użyć go bez dołączania wektora, np .:

int main ()
{
    Foo(3);
}

... Albo możemy używać go z std::vector , np .:

#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));
}

Nie sprawdzałem standardów, ale działa to clang/ gccz -std=c++98maksymalnie do -std=c++17, więc jeśli nie jest to oficjalnie norma, to wygląda na to, że jest nieoficjalnie.

Elliott
źródło
Może zapomniałeś o pustych nawiasach kątowych Foo<> foo;.
oleksijp