C++17: wie komme ich in dem static template an mein Basis-Using?

Gast #6904360
Lesenswert?

Ich hab eine etwas größere Template-Orgie unter VS2019 gefeiert und dann 
ein wenig spät meine üblichen Quertests mit gcc/clang unter Linux 
gemacht
leider bekomme ich bei dem unteren Code unter gcc diese Fehlermeldung:
1
19:79: error: expected initializer before '>' token

ich hab dann mein Szenario (aus sehr vielen hpps/cpps) relativ stark 
(nicht unbedingt sinnvoll) zusammengedampft um den Fehler in ein kleines 
Beispiel zu bringen- nochmal: das Beispiel ist nicht logisch oder 
strukturell sinnvoll - es ist nur der selbe Fehler

kann mir jemand sagen warum in der B::test das Change_callback using 
nicht gefunden wird - ohne ist mir klar - aber qualifiziert mit A:: 
muesste Change_callback doch erreichbar sein, oder?

mit A:: bekomme ich diesen Fehler
1
19:82: error: qualified-id in declaration before '>' token

zum spielen gcc.godbolt: https://gcc.godbolt.org/z/fT69s6KG9
1
#include <functional>
2

3
struct A
4
{
5
   using Change_callback = std::function<void( int value_ )>;
6
};
7

8
struct Callback_mapper
9
{
10
    template <auto OuterCallbackMethod, typename InnerCallback>
11
    InnerCallback create() const { return [&]( auto&&... args ){}; }
12
};
13

14
struct B: A
15
{
16
    template <auto CallbackMethod, typename CallbackMapper>
17
    static void test( const CallbackMapper& cm_ )
18
    {
19
        auto name_change_callback = cm_.create<CallbackMethod, A::Change_callback>();
20
    }
21
};
Persönliche Seite #6904370
Lesenswert?

Weil der Compiler beim Parsen (was ja VOR dem Einsetzen von Argumenten 
passiert - außer bei MSVC!) nicht genau weiß was "cm_" ist, weiß er auch 
nicht dass "create" ein template ist. Er nimmt an, create ist eine 
normale Member-Variable, und parst das "cm_.create < CallbackMethod" als 
kleiner-Operator. Das geht natürlich schief.

Lösen lässt sich das indem man
1
cm_.template create<CallbackMethod, A::Change_callback>();
schreibt. Dies zeigt dem Compiler an, dass "create" ein template ist, 
und nach dem "<" template-Argumente kommen.

Dass der MSVC das ohne "template" durchgehen lässt, ist nicht 
standard-konform, der Standard erfordert das "template". Beim MSVC geht 
es deswegen, weil er templates erst dann parst, wenn sie eingesetzt 
werden. Dadurch fallen einige Fehler nicht oder erst später auf, und 
andere korrekte Dinge funktionieren nicht. Bei MS ist halt alles immer 
etwas speziell :)
Gast #6904410
Lesenswert?

Niklas G. schrieb:
> Dass der MSVC das ohne "template" durchgehen lässt, ist nicht
> standard-konform, der Standard erfordert das "template". Beim MSVC geht
> es deswegen, weil er templates erst dann parst, wenn sie eingesetzt
> werden. Dadurch fallen einige Fehler nicht oder erst später auf, und
> andere korrekte Dinge funktionieren nicht. Bei MS ist halt alles immer
> etwas speziell :)

Danke Niklas für die Bestätigung meiner Vermutung und Lösung

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren