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


von cppbert (Gast)


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

von Niklas G. (erlkoenig) Benutzerseite


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 :)

: Bearbeitet durch User
von cppbert (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.