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