sfinae

sfinae with decltype: bug in clang or gcc?

不羁的心 提交于 2019-12-21 04:11:13
问题 Clang-3.2 can compile and code behave as expected: struct have_f { int f(int i) {return 10;} }; struct empty {}; template <class T> struct outer { T t; // if T have f(), define outer_f() template<class U=decltype(t.f(1))> int outer_f(int i) { return t.f(i); } }; int main() { outer<have_f> o1; outer<empty> o2; // to silence unused var warning return o1.outer_f(10) + sizeof(o2); } GCC of any version rejects with: t.cc:13:6: error: ‘struct empty’ has no member named ‘f’ int outer_f(int i) {

Making `std::get` play nice with SFINAE

心不动则不痛 提交于 2019-12-20 17:41:28
问题 std::get does not seem to be SFINAE-friendly, as shown by the following test case: template <class T, class C> auto foo(C &c) -> decltype(std::get<T>(c)) { return std::get<T>(c); } template <class> void foo(...) { } int main() { std::tuple<int> tuple{42}; foo<int>(tuple); // Works fine foo<double>(tuple); // Crashes and burns } See it live on Coliru The goal is to divert the second call to foo towards the second overload. In practice, libstdc++ gives: /usr/local/bin/../lib/gcc/x86_64-pc-linux

Making `std::get` play nice with SFINAE

≯℡__Kan透↙ 提交于 2019-12-20 17:41:28
问题 std::get does not seem to be SFINAE-friendly, as shown by the following test case: template <class T, class C> auto foo(C &c) -> decltype(std::get<T>(c)) { return std::get<T>(c); } template <class> void foo(...) { } int main() { std::tuple<int> tuple{42}; foo<int>(tuple); // Works fine foo<double>(tuple); // Crashes and burns } See it live on Coliru The goal is to divert the second call to foo towards the second overload. In practice, libstdc++ gives: /usr/local/bin/../lib/gcc/x86_64-pc-linux

When to use `static_assert` instead of SFINAE?

社会主义新天地 提交于 2019-12-20 08:49:25
问题 I have been using (and seen used) static_assert to flag undesired values of template parameter values. However, for all cases I came across it seems better and more elegant to disable those undesired values via SFINAE. For example template<typename T, class = std::enable_if<std::is_floating_point<T>::value>::type> struct Foo { ... }; instead of template<typename T> struct Foo { static_assert(std::is_floating_point<T>::value, "Foo<T>: T must be floating point :-("); ... }; So my question: when

Is the “lazy man's enable_if” legal C++?

走远了吗. 提交于 2019-12-20 08:46:20
问题 I frequently use a technique I call the "lazy man's enable_if ," where I use decltype and the comma operator to enable a function based on some template input. Here is a small example: template <typename F> auto foo(F&& f) -> decltype(f(0), void()) { std::cout << "1" << std::endl; } template <typename F> auto foo(F&& f) -> decltype(f(0, 1), void()) { std::cout << "2" << std::endl; } With --std=c++11 , g++ 4.7+ and Clang 3.5+ happily compile that bit of code (and it works as I would expect).

Writing a function template that is specialised for a class and its subclasses

岁酱吖の 提交于 2019-12-20 07:16:29
问题 I am trying to write a function template. One version should be used for all types that don't satisfy the criteria for the other version; the other version should be used when the argument is a base class of a given class, or that class itself. I have tried doing an overload for Base& , but when classes are derived from Base , they use the general one, not the specific one. I also have tried this SFINAE approach: struct Base { }; struct Derived : public Base { }; struct Unrelated { };

SFINAE did not compile [duplicate]

蹲街弑〆低调 提交于 2019-12-20 02:53:01
问题 This question already has answers here : SFINAE working in return type but not as template parameter (3 answers) Closed 4 years ago . Very often I used SFINAE before but I have a very very simple example I can't get to run today. class X { public: template <typename CHECK, typename = typename std::enable_if< std::is_floating_point<CHECK>::value, void>::type > void Do() { std::cout << "yes" << std::endl; } template <typename CHECK, typename = typename std::enable_if< !std::is_floating_point

How does this SFINAE C++ syntax work?

走远了吗. 提交于 2019-12-20 01:39:55
问题 I have just begun dabbling with SFINAE and I am having trouble understanding the syntax behind the most often-used example which appears in various forms, but the idea is to check whether a particular type contains a given member. This particular one is from Wikipedia: template <typename T> struct has_typedef_foobar { typedef char yes[1]; typedef char no[2]; template <typename C> static yes& test(typename C::foobar*); template <typename> static no& test(...); static const bool value = sizeof

Strange MSVC behaviour with std::experimental::is_detected

ぐ巨炮叔叔 提交于 2019-12-19 10:17:42
问题 I implemented std::experimental::is_detected based on this article on cppreference.com (Part of the code is below + working repro). It works well on G++ and Clang++, but results in strange errornous behaviour with MSVC: is_detected seems to always be bool_constant<true> ! Here you can see the correct result using gcc 5.x : @ideone.com But with MSVC 19 (shipped with VS2015) the tests always succeed: Z:\>cl /EHsc test.cxx .... Z:\>test true, true So, is this a known bug in the compiler? Is it

Using `void_t` to detect multiple inheritance type repetition errors

这一生的挚爱 提交于 2019-12-19 05:54:37
问题 I want to implement a has_no_duplicates<...> type trait that evaluates to std::true_type if the passed variadic type list has no duplicate types. static_assert(has_no_duplicates<int, float>{}, ""); static_assert(!has_no_duplicates<float, float>{}, ""); Let's assume, for the scope of this question, that I want to do that using multiple inheritance. When a class inherits from the same type more than once, an error occurs. template<class T> struct type { }; template<class... Ts> struct dup