2017-02-18 6 views
0

Überprüfung Wir haben:Explizite Instanziierung für Konzept

template<typename T> 
struct A { 
    void foo(int a) { 
    T::foo(a); 
    } 
}; 

template<typename T> 
struct B { 
    template struct A<T>; // concept check 
}; 

So definiere ich eine Ein Konzept-Prüfer, der T überprüft durch foo T Spedition :: foo.

Nun möchte ich überprüfen, ob das an B übergebene Argument das Konzept A durch explizite Instanziierung erfüllt, aber der Compiler beschwert sich, dass es der falsche Namensraum ist. Wie kann ich das beheben?

+0

'A' ist kein Konzept. Es ist eine 'Struktur'. Selbst mit Concepts TS ist es immer noch eine Struktur; In Konzepten TS sind Konzepte entweder Funktionen oder Variablen. Ihre Frage scheint also verwirrt zu sein. –

+0

Okay, ignoriere die Verwirrung. Wie setze ich den Scheck ein? – user3612643

+0

Wenden Sie welche Prüfung an? Wie bereits festgestellt, überprüft 'A' * nichts *. –

Antwort

0

So fand ich ein funktionierendes Beispiel:

#include <tuple> 

template<typename A> 
struct IA : A { 
    void foo(int a) { 
     A::foo(a); 
    } 

    void bar(double a) { 
     A::bar(a); 
    } 

    static constexpr auto $ = std::make_tuple(&IA::foo, &IA::bar); 
}; 

template<typename T> 
struct B { 
    // trigger concept/interface check of T "implements" IA 
    static constexpr auto $ = IA<T>::$; 
}; 

struct Test { 
    void foo(int a) {} 
    void bar(int a, int b) {} 
}; 

int main() { 
    B<Test> b; 
    b = b; 
} 

Die Generierung von $ in den Strukturen löst die Kompilierung aus. Der Compiler im obigen Beispiel beschwert sich korrekt mit:

In instantiation of 'void IA<A>::bar(double) [with A = Test]': 
13:57: required from 'constexpr const std::tuple<void (IA<Test>::*)(int), void (IA<Test>::*)(double)> IA<Test>::$' 
18:27: recursively required from 'constexpr const std::tuple<void (IA<Test>::*)(int), void (IA<Test>::*)(double)> B<Test>::$' 
18:27: required from 'struct B<Test>' 
28:13: required from here 
10:17: error: no matching function for call to 'IA<Test>::bar(double&)' 
10:17: note: candidate is: 
24:10: note: void Test::bar(int, int) 
24:10: note: candidate expects 2 arguments, 1 provided 
+0

Variablen mit dem Namen '$' sind nicht zulässig C++. – Yakk

+0

Kann jemand das obige Beispiel ändern, so dass es kein globales "statisches" erstellen muss? – user3612643

1

So etwas wie dies vielleicht:

template<typename T, void(T::*)(int)> 
struct A {}; 

template<typename T> 
struct B { 
    using Check = A<T, &T::foo>; 
}; 

Demo


Oder diese:

template<typename T> 
struct B { 
    static_assert(
    std::is_same<decltype(&T::foo), void(T::*)(int)>::value, 
    "No T::foo(int) member"); 
}; 
Verwandte Themen