#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.