简体   繁体   中英

C++ function template overload resolution with nested types

Why does overload resolution fail in this case? I would have expected that foo<int> could be deduced.

template <typename T> struct Templ { typedef T Type; };
template <typename T> void foo(typename Templ<T>::Type) {}
foo(1);          //error can't deduce template argument for T

The rules of C++ say that's not a deduced context. If one thinks about why that might be, there are a few things that comes to mind.

Deduction in this case is asking the compiler to invert a type-level function. That may be ambiguous or impossible. That requires introducing rules around specialization visibility. And such a function may be complex even when the solution is unambiguous:

template <std::uint32_t>
struct foo;

template <>
struct foo<0u> {
    using type = std::integral_constant<int, 1>;
};

template <>
struct foo<1u> {
    using type = std::integral_constant<int, 2>;
};

template <std::uint32_t N>
struct foo {
    using type = std::integral_constant<int,
        foo<N-1>::type::value + foo<N-2>::type::value
    >;
};

template <std::uint32_t N>
void using_foo(typename foo<N>::type); 

// would deduce N=20u
using_foo(std::integral_constant<int, 17711>{});

Additionally, it seems like deduction in such cases would introduce ODR hazards. By calling a function, with some arbitrary parameter, we would be deducing a parameter type through an unrelated type-function, and we require that the relevant specializations of that type-function be visible, which isn't something that's obvious at all at the call site.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM