sfinae

Why do you sometimes need to write `typename T` instead of just `T`?

流过昼夜 提交于 2019-12-12 07:50:14
问题 I was reading the Wikipedia article on SFINAE and encountered following code sample: struct Test { typedef int Type; }; template < typename T > void f( typename T::Type ) {} // definition #1 template < typename T > void f( T ) {} // definition #2 void foo() { f< Test > ( 10 ); //call #1 f< int > ( 10 ); //call #2 without error thanks to SFINAE } Now I've actually written code like this before, and somehow intuitively I knew that I needed to type "typename T" instead of just "T". However, it

Is it possible to call a member function for every type in a tuple?

与世无争的帅哥 提交于 2019-12-12 04:45:09
问题 namespace details { template <std::size_t I = 0, typename Tuple, typename Function, typename... Args> typename std::enable_if<I == std::tuple_size<Tuple>::value, void>::type ForEach(Tuple &t, Function f, Args &... args) {} template <std::size_t I = 0, typename Tuple, typename Function, typename... Args> typename std::enable_if<(I < std::tuple_size<Tuple>::value), void>::type ForEach(Tuple &t, Function f, Args &... args) { f(std::get<I>(t), args...); ForEach<I + 1>(t, f, args...); } } An

Why Can't These Templatized Functions Take No Arguments?

半城伤御伤魂 提交于 2019-12-12 04:06:58
问题 I am trying to use a couple templatized functions for Substitution Fail Is Not An Error(SFINAE). And I can do it like this: template<typename R, typename S = decltype(declval<R>().test())> static true_type Test(R*); template<typename R> static false_type Test(...); But I'm not understanding how the argument makes this SNFIAE work. It seems like I should just be able to remove the arguments and the template selection would work the exact same way: template<typename R, typename S = decltype

Is There a declval for Function Pointers?

泄露秘密 提交于 2019-12-11 17:51:33
问题 I have a function and I need to test whether I can pass an argument of a given type to it. For example: template<typename T, auto F> decltype(F(declval<T>{})) foo(); Calling foo<int, bar>() does 2 things: Sets the return type of foo would have the same return type as bar Ensures that bar is a function that accepts an argument of type T Unfortunately I don't have access to auto template types, but I still want to accomplish both of these. What I need is a decltype for function pointers, which

Forcing SFINAE With a Different Return Type

给你一囗甜甜゛ 提交于 2019-12-11 17:34:51
问题 So this answer demonstrates how I can use a function in the return type to force Substitution Failure is not an Error (SFINAE). Is there a way that I can use this and have a different return type from the function? So a arguments line this to overload will trigger the SFINAE: overload { [&](auto& value) -> decltype(void(value.bar())) { value.bar(); } , [](fallback_t) { cout << "fallback\n"; } } But lets say that I need a different return type, how can I still trigger SFINAE? For example I'd

SFINAE and std::numeric_limits

大兔子大兔子 提交于 2019-12-11 15:40:36
问题 I am trying to write a stream class that handles numerical and non-numerical data separately. Can someone explain to me why this code does not compile? #include <iostream> #include <cstdlib> #include <type_traits> #include <limits> class Stream { public: Stream() {}; template<typename T, typename std::enable_if_t<std::numeric_limits<T>::is_integer::value>> Stream& operator<<(const T& val) { std::cout << "I am an integer type" << std::endl; return *this; }; template<typename T, typename std:

How to get a SFINAE expression to work with template and non-template classes?

匆匆过客 提交于 2019-12-11 14:57:00
问题 I have made this for SFINAE: // Type 'type' exists iff X is a base of COLLECTION template<typename X, typename COLLECTION, typename RET_TYPE = void> struct enable_if_is_base_of : std::enable_if<std::is_base_of<X, COLLECTION>::value, RET_TYPE> {}; Which works well for something like this: class A {}; class B {}; class C{}; class collection : A, B {}; template <typename X> typename enable_if_is_base_of<X, collection>::type fn(X&& x) { } int main() { fn(A()); fn(B()); // fn(C()); // Fails as

Why can we detect the presence of default parameter values of operator() with SFINAE, but not those of free functions and PMFs?

隐身守侯 提交于 2019-12-11 11:13:57
问题 In the program below, case 1 attempts to use a default parameter via pointer-to-member-function. Case 2 attempts to use a default parameter via function reference. Case 3 uses the default parameter in operator() . The only interesting assertions here are the ones using the alias can_call_with_one - the others exist to prove correctness of the setup. In the latest versions of GCC, Clang, and MSVC that are available to me, this program fails the single-argument assertions in cases 1 and 2. My

How to test if template function exists at compile time

浪子不回头ぞ 提交于 2019-12-11 10:59:22
问题 I have the following template function template<class Visitor> void visit(Visitor v,Struct1 s) { } How to check if this function exists at compile time with SFINAE 回答1: Without more details I can only guess what you have available, but here's a possible solution: //the type of the call expression to visit with a given Visitor //can be used in an SFINAE context template <class Visitor> using visit_t = decltype(visit(std::declval<Visitor>(), std::declval<Struct1>())); //using the void_t pattern

Conditional overloading with trailing-return-type possible?

久未见 提交于 2019-12-11 07:25:03
问题 Suppose you attempt to do the following: template</* args */> typename std::enable_if< /*conditional*/ , /*type*/ >::type static auto hope( /*args*/) -> decltype( /*return expr*/ ) { } Is it possible to combine conditional inclusion/overloading ( std::enable_if ) with trailing-return-type ( auto ... -> decltype() )? I would not be interesting in solutions using the preprocessor. I can always do things like #define RET(t) --> decltype(t) { return t; } and extend it to take also the whole