#include <iostream> #include <sstream> template <class... Ts> struct Y { static_assert(sizeof...(Ts)>0, "!"); // assert here due to // operator<< will try to instantiate Y<Ts...> to match // std::endl with sizeof...(Ts) == 0; // If it's T instead of Ts..., T will not be matched and // simply an SFINAE and fall back to main template function // operator << }; template <class... Ts> std::ostream& operator<<(std::ostream& os, Y<Ts...> const& ) { return os << std::endl; } // Match to &std::endl; which endl is a template function. std::basic_ostream<char, std::char_traits<char> >& (*endl) (std::basic_ostream<char, std::char_traits<char> >&) = &std::endl; // Same as above, difference is using typename T to match // template function std::endl; template<typename T> std::basic_ostream<T, std::char_traits<T> >& (*endl_2) (std::basic_ostream<T, std::char_traits<T> >&) = &std::endl; // --------------------------------- template<typename T, typename U = T> struct Fun{ }; // Mark out main template to prevent SFINAE /*template<typename T> void ha(T t){}*/ template<typename T> void ha(Fun<T> f){ /*ha(std::endl);*/ ha(2.0); } template<typename... T> void ha2(Fun<T...> f){ ha2(2.0); } int main() { // call template operator << operator <<(std::cout, Y<int>{}); } /* Error: test.cpp:7:5: error: static_assert failed "!" static_assert(sizeof...(Ts)>0, "!"); ^ ~~~~~~~~~~~~~~~ test.cpp:21:18: note: in instantiation of template class 'Y<>' requested here return os << std::endl; ^ test.cpp:53:5: error: no matching function for call to 'ha' ha(2.0); ^~ test.cpp:51:6: note: candidate template ignored: could not match 'Fun<type-parameter-0-0, type-parameter-0-0>' against 'double' void ha(Fun<T> f){ ^ test.cpp:59:5: error: no matching function for call to 'ha2' ha2(2.0); ^~~ test.cpp:58:6: note: candidate template ignored: could not match 'Fun<type-parameter-0-0...>' against 'double' void ha2(Fun<T...> f){ ^ 3 errors generated. */
Dec 14, 2016
[C++] [template] Ts... during template function argument type matching will generate sizeof...(Ts) == 0 is argument is not dependent
Google ISO C++ Standard - Discussion
Variant's trap when overloading operator<<
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.