Ich versuche, über alle Basisklassen einer variadic abgeleiteten Klasse "iterieren" und rufen Sie eine Methode namens "Stream", wenn es existiert.mit sfinae zu erkennen, ob Basisklassen einer variadic Vorlage spezifische Methode haben
Um zu überprüfen, ob eine Methode existiert, benutze ich sfinae, und es funktioniert (siehe auskommentierten Code). Aber wenn ich es mit variadischer Vorlage "Iteration" kombiniere, wenn es nicht funktioniert, sieht der Fehler irgendwie so aus, als ob der Sfinae-Teil plötzlich nicht wie erwartet funktioniert, wenn er innerhalb der variadischen Magie ist.
Hilfe geschätzt. Ich benutze gcc 5.3.0.
#include <type_traits>
#include <iostream>
namespace detail{
template<class> struct sfinae_true : std::true_type{};
template<class T, class A0, class A1> static auto test_stream(int) -> sfinae_true<decltype(
std::declval<T>().stream(std::declval<A0>(), std::declval<A1>()))>;
template<class, class A0, class A1> static auto test_stream(long) -> std::false_type;
}
template<class T, class A0, class A1> struct has_stream : decltype(detail::test_stream<T, A0, A1>(0)){};
struct X{ void stream(int, bool){} };
struct A{ void stream(int, bool){} };
struct Y{};
template <typename ... T> class Z : public T ... {
public:
void ff() {
std::initializer_list<bool> {
(has_stream<T,int,bool>() ? (T::stream(0, 0) , true) : false) ...
};
}
};
int main(){
Z<X,A> a;
Z<X,A,Y> b;
/* this works as expected.
// this runs
if (has_stream<X, int, bool>()) {
std::cout << "has int, bool" << std::endl;
}
// and this doesn't
if (has_stream<Y, int, long>()) {
std::cout << "has int long" << std::endl;
}
*/
a.ff(); // no error
b.ff(); // error
}
$ g++ --std=c++14 -O0 2.cpp
2.cpp: In instantiation of ‘void Z<T>::ff() [with T = X, A, Y]’:
2.cpp:41:10: required from here
2.cpp:22:52: error: ‘stream’ is not a member of ‘Y’
(has_stream<T,int,bool>() ? (T::stream(0, 0) , true) : false) ...
^
2.cpp:21:9: error: no matching function for call to ‘std::initializer_list<bool>::initializer_list(<brace-enclosed initializer list>)’
std::initializer_list<bool> {
^
Klingt wie ein [Konzepte] (https://en.wikipedia.org/wiki/Co ncepts_ (C% 2B% 2B)) Problem. – erip
Könnten Sie bitte genauer sein? von dem, was ich von dem Artikel bekommen habe - Konzepte sind in C++ 14 nicht verfügbar. Ich sehe keinen Grund, warum mein Code nicht in C++ 14 funktionieren sollte (du machst mir keinen Vorwurf, aber ich selbst, versteh mich nicht falsch). –
Ich schlage nicht vor, dass Ihr gewünschtes Verhalten im Bereich von C++ 14 unmöglich ist. Ich sage, dass dies ein guter Kandidat für Konzepte zu sein scheint, die derzeit (und in absehbarer Zukunft) nicht verfügbar sind. – erip