sfinae

What does the 'void()' in 'auto f(params) -> decltype(…, void())' do?

荒凉一梦 提交于 2019-12-03 18:38:04
问题 I found code here that looked something like this: auto f(T& t, size_t n) -> decltype(t.reserve(n), void()) { .. } In all the documentation I read I was told that decltype is signed as: decltype( entity ) or decltype( expression ) And there is no second argument anywhere. At least that's what's pointed to on cppreference. Is this a second argument to decltype ? And if so, what does it do? 回答1: Since it is an expression that comma is simply the comma operator (meaning the type is the type of

How to write the best possible is_callable trait for templated operator()

无人久伴 提交于 2019-12-03 18:01:44
问题 I have is_callable trait defined like this: #ifndef IS_CALLABLE_HPP #define IS_CALLABLE_HPP #include <type_traits> namespace is_callable_detail { struct no {}; struct yes { no x[2]; }; template<bool CallableArgs, typename Callable, typename ReturnType, typename ...Args> struct check_return { static const bool value = std::is_convertible<decltype(std::declval<Callable>()(std::declval<Args>()...)), ReturnType>::value; }; template<typename Callable, typename ReturnType, typename ...Args> struct

traits for testing whether func(args) is well-formed and has required return type

偶尔善良 提交于 2019-12-03 16:23:41
There are a number of similar questions/answers, but I couldn't quite put those answers together to serve my purposes. I want a traits template<typename Func, typename ReturnType, typename... Args> struct returns_a { static const bool value; }; such that returns_a<F,T,Args>::value is true if F(Args) is well formed and returns a T . After some more research, I got it working as follows: // value is true if Func(Args...) is well formed template<typename Func, typename... Args> class is_callable { template <typename F> static decltype(std::declval<F>()(std::declval<Args>()...), void(), 0) test

void_t fails on Visual Studio 2015

余生长醉 提交于 2019-12-03 15:20:01
问题 I don't understand why the following test always fails with Visual Studio 2015 (the static_assert triggers): #include <type_traits> using namespace std; template<class T> using try_assign = decltype(declval<T&>() = declval<T const&>()); template<class, class = void> struct my_is_copy_assignable : false_type {}; template<class T> struct my_is_copy_assignable<T, void_t<try_assign<T>>> : true_type {}; int main() { static_assert(my_is_copy_assignable<int>::value, "fail"); return 0; } It's

SFINAE to assert() that code DOES NOT compile

…衆ロ難τιáo~ 提交于 2019-12-03 14:52:35
I feel certain it must be possible to use SFINAE (possibly with Macros) to static_assert() that arbitary code will not compile. There are some complex cases in my code-base, where i have a class that I want to forbid taking temporaries (I believe the pattern is): class(const class&& tmp)=delete; /* deny copying from an unnamed temporary */ class (class&& rhs){/* allow construction from non-temporary rvalue*/} Currently, I check an undesired constructor DOES NOT compile, but then of course I have to comment it out to get the tests to compile again! If I could do: static_assert(DOES_NOT_COMPILE

std::enable_if or SFINAE for iterator or pointer

▼魔方 西西 提交于 2019-12-03 14:35:54
I would like to write a constructor for MyClass that take an argument and I want this to compile only if the argument is a pointer or an iterator (something having iterator_traits ). How to achieve this ? Regrettably, there is no standard way to detect whether a class models Iterator . The simplest check would be that *it and ++it are both syntactically valid; you can do this using standard SFINAE techniques: template<typename T, typename = decltype(*std::declval<T&>(), void(), ++std::declval<T&>(), void())> MyClass(T); Considering the Iterator requirements from 24.2.2:2: template<typename T>

SFINAE: detect if class has free function

落花浮王杯 提交于 2019-12-03 13:34:42
问题 Is there a way, using SFINAE, to detect whether a free function is overloaded for a given class? Basically, I’ve got the following solution: struct has_no_f { }; struct has_f { }; void f(has_f const& x) { } template <typename T> enable_if<has_function<T, f>::value, int>::type call(T const&) { std::cout << "has f" << std::endl; } template <typename T> disable_if<has_function<T, f>::value, int>::type call(T const&) { std::cout << "has no f" << std::endl; } int main() { call(has_no_f()); // "has

SFINAE to test a free function from another namespace

和自甴很熟 提交于 2019-12-03 13:08:37
I was trying to come up with a hack to test if std::isnan is defined without special casing compilers in the preprocessor, and came up with the following, which I was expecting to work fine. #include <cmath> #include <type_traits> namespace detail { using namespace std; struct dummy {}; void isnan(dummy); //bool isnan(float); // Just adding this declaration makes it work! template <typename T> struct is_isnan_available { template <typename T1> static decltype(isnan(T1())) test(int); template <typename> static void test(...); enum { value = !std::is_void<decltype(test<T>(0))>::value }; }; } int

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

a 夏天 提交于 2019-12-03 12:49:43
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 would be nice to know the actual logic behind it. Anyone care to explain? In general, C++'s syntax

How to resolve ambiguity in overloaded functions using SFINAE

感情迁移 提交于 2019-12-03 12:42:16
I have an incredibly exciting library that can translate points: it should work with any point types template<class T> auto translate_point(T &p, int x, int y) -> decltype(p.x, p.y, void()) { p.x += x; p.y += y; } template<class T> auto translate_point(T &p, int x, int y) -> decltype(p[0], void()) { p[0] += x; p[1] += y; } translate_point will work with points that have public x and y members, and it will also work with tuples/indexable containers where x and y are represented by the first and second element, respectively. The problem is, another library defines a point class with public x and