Pytanie Specjalizacja szablonu funkcji członka po błędzie wystąpienia i kolejności funkcji składowych


Poniższy fragment kodu nie kompiluje się w gcc 4.5.3

struct Frobnigator
{
    template<typename T>
    void foo();

    template<typename T>
    void bar(); 
};

template<typename T>
void Frobnigator::bar()
{
}

template<typename T>
void Frobnigator::foo()
{
    bar<T>();
}

template<>      // error
void Frobnigator::foo<bool>()
{
    bar<bool>();
}

template<>
void Frobnigator::bar<bool>()
{
}

int main()
{
}

Komunikat o błędzie: specialization of ‘void Frobnigator::bar() [with T = bool]’ after instantiation. W końcu rozwiązałem ten problem przez specjalizację Frobnigator::bar<bool>() pojawiają się wcześniej Frobnigator::foo<bool>(). Oczywiście kolejność, w jakiej pojawiają się metody, ma znaczenie.

Dlaczego więc jest następująca lite wersja powyższego kodu, w którym specjalizacja bar pojawia się po wersji ogólnej, ważne?

struct Frobnigator
{
    template<typename T>
    void foo();
};

template<typename T>
void Frobnigator::bar()
{
}

template<>
void Frobnigator::bar<bool>()
{
}

int main()
{
}

14
2018-01-14 11:14


pochodzenie




Odpowiedzi:


Twój pierwszy kod jest nieprawidłowy według standardu.

n3376 14.7.3 / 6

Jeśli szablon, szablon członkowski lub członek szablonu klasy jest wyraźnie wyspecjalizowany specjalizacja zostanie zadeklarowana przed pierwszym użyciem tej specjalizacji, która spowodowałaby implicite założenie mieć miejsce, w każdej jednostce tłumaczeniowej, w której następuje takie wykorzystanie; diagnostyka nie jest wymagana.

W twoim przypadku - implicite utworzenie bar funkcja z typem bool jest wymagane przez jego użycie w foo<bool>przed wyraźną deklaracją specjalizacyjną.


21
2018-01-14 11:21





Oczywiście kolejność, w jakiej pojawiają się metody, ma znaczenie.

W rzeczy samej; jak to zwykle bywa w C ++, nie można użyć czegoś, zanim zostanie zadeklarowane, i dotyczy to wyraźnych specjalizacji szablonów, jak również większości innych rzeczy.

Za pomocą bar<bool> (przez wywołanie go z foo<bool>) bez wcześniejszej deklaracji o wyraźnej specjalizacji powoduje, że specjalizacja jest tworzona z szablonu ogólnego, jeśli jeszcze jej nie było. Będziesz potrzebował co najmniej deklaracji wyraźnej specjalizacji, aby temu zapobiec.

Dlaczego tak jest, biorąc pod uwagę, że specjalizacja paska pojawia się po wersji ogólnej w poniższej wersji kodu powyższego kodu

Drugi przykład różni się od braku instancji foo<bool> w ogóle. Problem nie polega na tym, że specjalizacja jest zadeklarowana po szablonie ogólnym (tak musi być), ale jest zadeklarowana po tym, jak specjalizacja została już utworzona.


2
2018-01-14 11:28