Don't require that, during template deduction, a template specialization type
as a function parameter has at least as many template arguments as one used in
a function argument (not even if the argument has been resolved to an exact
type); the additional parameters might be provided by default template
arguments in the template. We don't need this check, since we now implement
[temp.deduct.call]p4 with an additional check after deduction.

llvm-svn: 169475
This commit is contained in:
Richard Smith 2012-12-06 06:44:44 +00:00
parent 1e3d387459
commit 16b65394ee
2 changed files with 17 additions and 13 deletions

View File

@ -130,8 +130,7 @@ DeduceTemplateArguments(Sema &S,
const TemplateArgument *Params, unsigned NumParams,
const TemplateArgument *Args, unsigned NumArgs,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
bool NumberOfArgumentsMustMatch = true);
SmallVectorImpl<DeducedTemplateArgument> &Deduced);
/// \brief If the given expression is of a form that permits the deduction
/// of a non-type template parameter, return the declaration of that
@ -482,8 +481,7 @@ DeduceTemplateArguments(Sema &S,
return DeduceTemplateArguments(S, TemplateParams,
Param->getArgs(), Param->getNumArgs(),
SpecArg->getArgs(), SpecArg->getNumArgs(),
Info, Deduced,
/*NumberOfArgumentsMustMatch=*/false);
Info, Deduced);
}
// If the argument type is a class template specialization, we
@ -1749,8 +1747,7 @@ DeduceTemplateArguments(Sema &S,
const TemplateArgument *Params, unsigned NumParams,
const TemplateArgument *Args, unsigned NumArgs,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
bool NumberOfArgumentsMustMatch) {
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
// C++0x [temp.deduct.type]p9:
// If the template argument list of P contains a pack expansion that is not
// the last template argument, the entire template argument list is a
@ -1770,8 +1767,7 @@ DeduceTemplateArguments(Sema &S,
// Check whether we have enough arguments.
if (!hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs))
return NumberOfArgumentsMustMatch? Sema::TDK_NonDeducedMismatch
: Sema::TDK_Success;
return Sema::TDK_Success;
if (Args[ArgIdx].isPackExpansion()) {
// FIXME: We follow the logic of C++0x [temp.deduct.type]p22 here,
@ -1867,11 +1863,6 @@ DeduceTemplateArguments(Sema &S,
return Result;
}
// If there is an argument remaining, then we had too many arguments.
if (NumberOfArgumentsMustMatch &&
hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs))
return Sema::TDK_NonDeducedMismatch;
return Sema::TDK_Success;
}

View File

@ -53,3 +53,16 @@ namespace DeduceNonTypeTemplateArgsInArray {
tuple<unsigned_c<1>, unsigned_c<2>, unsigned_c<3>>
>::value? 1 : -1];
}
namespace DeduceWithDefaultArgs {
template<template<typename...> class Container> void f(Container<int>); // expected-note {{substitution failure [with Container = X]}}
template<typename, typename = int> struct X {};
void g() {
// OK, use default argument for the second template parameter.
f(X<int>{});
f(X<int, int>{});
// Not OK.
f(X<int, double>{}); // expected-error {{no matching function for call to 'f'}}
}
}