1// { dg-options "-std=gnu++11" } 2// { dg-do compile } 3 4// Copyright (C) 2012-2015 Free Software Foundation, Inc. 5// 6// This file is part of the GNU ISO C++ Library. This library is free 7// software; you can redistribute it and/or modify it under the 8// terms of the GNU General Public License as published by the 9// Free Software Foundation; either version 3, or (at your option) 10// any later version. 11 12// This library is distributed in the hope that it will be useful, 13// but WITHOUT ANY WARRANTY; without even the implied warranty of 14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15// GNU General Public License for more details. 16 17// You should have received a copy of the GNU General Public License along 18// with this library; see the file COPYING3. If not see 19// <http://www.gnu.org/licenses/>. 20 21// Taken from N3436: 22 23#include <type_traits> 24#include <string> 25 26struct eat { template<typename T> eat(T const &) {} }; 27struct not_incrementable {}; 28 29struct inc { 30 template<typename T> 31 auto operator()(T t) const -> decltype(t++) 32 { return t++; } 33}; 34 35template<typename A> 36typename std::result_of<inc(A)>::type // sfinae here 37try_inc(A a) { 38 return inc()(a); 39} 40 41not_incrementable 42try_inc(eat) { 43 return not_incrementable(); 44} 45 46template<typename> 47struct never { static const bool value = false; }; 48 49template<typename T> 50struct Fail 51{ 52 static_assert(never<T>::value, "duh"); 53 typedef int type; 54}; 55 56struct Fun 57{ 58 template<typename T> 59 typename Fail<T>::type operator()(T) 60 { return 0; } 61}; 62 63template<typename T> 64typename std::result_of<Fun(T)>::type foo(T) 65{ return 0; } 66 67template<typename> 68int foo(...) 69{ return 0; } 70 71void result_of_sfinae() { 72 int x = try_inc(1); // OK 73 not_incrementable y = try_inc(std::string("foo")); // OK, not_incrementable 74 (void) x; 75 (void) y; 76} 77