func<__Ts...>(obj);
- here, despite you manually specifying the template arguments, the compiler still performs deduction and appends one extra type to the pack, based on obj
's type. Apparently this gets priority over converting obj
to a different type.
auto p = func<__Ts...>; p(obj);
- here you prevented template argument deduction; template arguments get baked into p
's type when deducing the auto
, and then aren't touched again.
One way to fix this is func(static_cast<const CTest<__Ts...> &>(obj));
.
There's a lot of weird things in your code, starting with
template<>void func(const CTest<> &obj)
This is a explicit specialization of the first foo
. Probably not what you intended. You end up with two overloads of func
as following:
1st overload:
template<typename ...__T> void func(const CTest<__T...> &)
- declared but not defined for some reason.This one has the explicit specialization:
template<> void func(const CTest<> &obj)
2nd overload:
template<typename __T, typename ...__Ts> void func(const CTest<__T, __Ts...> &obj)
Specializing function templates is usually best avoided. Just make that overload non-template:
void func(const CTest<> &obj) {}template<typename __T, typename ...__Ts>void func(const CTest<__T, __Ts...> &obj) {...}