In [temp.arg.explicit]/3, we have this amazing sentence:
A trailing template parameter pack not otherwise deduced will be deduced to an empty sequence of template arguments.
What does this mean? What is a trailing template parameter pack? What does not otherwise deduced mean? These are all good questions that don't really have answers. But this has very interesting consequences. Consider:
template <typename... Ts> void f(std::tuple<Ts...>);
f({}); // ok??
This is... well-formed. We can't deduce Ts...
so we deduce it as empty. That leaves us with std::tuple<>
, which is a perfectly valid type - and a perfectly valid type that can even be instantiated with {}
. So this compiles!
So what happens when the thing we deduce from the empty parameter pack we conjured up isn't a valid type? Here's an example:
template <class... Ts>
struct Y
{
static_assert(sizeof...(Ts)>0, "!");
};
template <class... Ts>
std::ostream& operator<<(std::ostream& os, Y<Ts...> const& )
{
return os << std::endl;
}
The operator<<
is a potential candidate, but deduction fails... or so it would seem. Until we conjure up Ts...
as empty. But Y<>
is an invalid type! We don't even try to find out that we can't construct a Y<>
from std::endl
- we have already failed.
This is fundamentally the same situation you have with variant
, because variant<>
is not a valid type.
The easy fix is to simply change your function template from taking a variant<Ts...>
to a variant<T, Ts...>
. This can no longer deduce to variant<>
, which isn't even a possible thing, so we don't have a problem.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…