fork download
  1. template<class T>
  2. struct wrapper { T t; };
  3.  
  4. // Checks if the type is instantiated from the wrapper
  5. template <typename...>
  6. struct sfinae_without_wrapper {};
  7.  
  8. template <typename H, typename... T>
  9. struct sfinae_without_wrapper<H, T...> { typedef typename sfinae_without_wrapper<T...>::type type; };
  10.  
  11. template <typename H, typename... T>
  12. struct sfinae_without_wrapper<wrapper<H>, T...> { typedef H type; };
  13.  
  14. // Returns the underlying object
  15. template <typename T> T const& base(T const& t) { return t; }
  16. template <typename T> T const& base(wrapper<T> const& w) { return w.t; }
  17.  
  18. // Operator
  19. template<class W, class X>
  20. auto operator+(const W& i, const X& j) ->
  21. decltype(typename sfinae_without_wrapper<W, X>::type{}, base(i) + base(j))
  22. {
  23. return base(i) + base(j);
  24. }
  25.  
  26. // Test case
  27. struct test { int i; };
  28.  
  29. int main() {
  30. test{1} + test{2};
  31. return 0;
  32. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp: In instantiation of ‘struct sfinae_without_wrapper<test>’:
prog.cpp:9:94:   required from ‘struct sfinae_without_wrapper<test, test>’
prog.cpp:21:59:   required by substitution of ‘template<class W, class X> decltype ((typename sfinae_without_wrapper<W, X>::type{}, (base(i) + base(j)))) operator+(const W&, const X&) [with W = test; X = test]’
prog.cpp:30:21:   required from here
prog.cpp:9:94: error: no type named ‘type’ in ‘struct sfinae_without_wrapper<>’
 struct sfinae_without_wrapper<H, T...> { typedef typename sfinae_without_wrapper<T...>::type type; };
                                                                                              ^
prog.cpp:21:77: error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) substituting ‘template<class T> const T& base(const T&) [with T = test]’
     decltype(typename sfinae_without_wrapper<W, X>::type{}, base(i) + base(j))
                                                                             ^
prog.cpp:21:69:   recursively required by substitution of ‘template<class W, class X> decltype ((typename sfinae_without_wrapper<W, X>::type{}, (base(i) + base(j)))) operator+(const W&, const X&) [with W = test; X = test]’
prog.cpp:21:69:   required by substitution of ‘template<class W, class X> decltype ((typename sfinae_without_wrapper<W, X>::type{}, (base(i) + base(j)))) operator+(const W&, const X&) [with W = test; X = test]’
prog.cpp:30:21:   required from here

prog.cpp: In function ‘int main()’:
prog.cpp:30:13: error: no match for ‘operator+’ (operand types are ‘test’ and ‘test’)
     test{1} + test{2};
             ^
prog.cpp:30:13: note: candidate is:
prog.cpp:20:6: note: template<class W, class X> decltype ((typename sfinae_without_wrapper<W, X>::type{}, (base(i) + base(j)))) operator+(const W&, const X&)
 auto operator+(const W& i, const X& j) ->
      ^
prog.cpp:20:6: note:   substitution of deduced template arguments resulted in errors seen above
stdout
Standard output is empty