c++ - Type deduction for non-viable function templates -
in his answer this question , comment section, johannes schaub says there's "match error" when trying template type deduction function template requires more arguments have been passed:
template<class t> void foo(t, int); foo(42); // template specialization foo<int>(int, int) not viable in context of other question, what's relevant whether or not type deduction function template succeeds (and substitution takes place):
template<class t> struct has_no_nested_type {}; // think need specialization following class template // `non_immediate_context` can instantiated, otherwise program // ill-formed, ndr template<> struct has_no_nested_type<double> { using type = double; }; // make error appear not in immediate context template<class t> struct non_immediate_context { using type = typename has_no_nested_type<t>::type; }; template<class t> typename non_immediate_context<t>::type foo(t, int) { return {}; } template<class t> bool foo(t) { return {}; } int main() { foo(42); // well-formed? clang++3.5 , g++4.8.2 accept foo<int>(42); // well-formed? clang++3.5 accepts it, not g++4.8.2 } when instantiating first function template foo t == int, substitution produces invalid type not in immediate context of foo. leads hard error (this the related question about.)
however, when letting foo deduce template-argument, g++ , clang++ agree no instantiation takes place. johannes schaub explains, because there "match error".
question: "match error", , , how specified in standard?
altenative question: why there difference between foo(42) , foo<int>(42) g++?
what i've found / tried far:
[over.match.funcs]/7 , [temp.over] seem describe overload resolution specifics function templates. latter seem mandate substitution of template parameters foo.
interestingly, [over.match.funcs]/7 triggers process described in [temp.over] before checking viability of function template (specialization). similarly, type deduction not take account, say, default function arguments (other making them non-deduced context). seems not concerned viability, far can tell.
another possibly important aspect how type deduction specified. acts on single function parameters, don't see distinction made between parameter types contain / dependent on template parameters (like t const&) , aren't (like int).
yet, g++ makes difference between explicitly specifying template parameter (hard error) , letting them deduced (deduction failure / sfinae). why?
what i've summarized process described @ 14.8.2.1p1
template argument deduction done comparing each function template parameter type (call p) type of corresponding argument of call (call a) described below.
in our case, have p (t, int) , a, have (int). first pair of p/a, t against int, can match t int (by process described in 14.8.2.5). second "pair", have int have no counterpart. deduction cannot made "pair".
thereby, 14.8.2.5p2, "if type deduction cannot done p/a pair, ..., template argument deduction fails.".
you won't ever come point substitute template arguments function template.
this can described more precisely in standard (imo), believe how 1 implement things match actual behavior of clang , gcc , seems reasonable interpretation of standardese.
Comments
Post a Comment