实例化函数模板时省略模板类型参数是否合法?
Is it legal to omit template type arguments when instantiating a function template?
以下代码实现了一个函数模板 foo
,它接受任意数量的参数,随后处理每个参数,同时维护该参数的位置索引:
template<int index, typename T>
void foo_impl(T value)
{
// Do something with index/value
}
template<int index, typename T, typename... Rest>
void foo_impl(T value, Rest... values)
{
// Do something with index/value
// Recursively handle remaining arguments
foo_impl<index + 1>(values...);
}
template<typename... T>
void foo(T... args)
{
foo_impl<1>(args...);
}
int main()
{
foo("test", 42);
}
这递归地实例化函数模板,直到它到达采用单个参数的基本模板。 foo_impl
的每个函数模板实例化都省略了模板类型参数。虽然这 compiles with Clang, GCC, and MSVC,但我不确定这是否合法。
如代码示例所示,省略模板参数是否合法?如果有,具体规则是什么?这些规则在 C++ 标准之间有变化吗?
具体规则在[temp.arg.explicit]
3 Trailing template arguments that can be deduced or obtained
from default template-arguments may be omitted from the list of
explicit template-arguments. A trailing template parameter pack not
otherwise deduced will be deduced to an empty sequence of template
arguments. If all of the template arguments can be deduced, they may
all be omitted; in this case, the empty template argument list <>
itself may also be omitted. In contexts where deduction is done and
fails, or in contexts where deduction is not done, if a template
argument list is specified and it, along with any default template
arguments, identifies a single function template specialization, then
the template-id is an lvalue for the function template specialization.
由于类型参数是尾随的,并且可以从函数调用的参数中推导出来,因此可以省略它们。
迄今为止的所有标准修订版中都存在这样的措辞(除了关于参数包的部分,C++03 中没有)。
以下代码实现了一个函数模板 foo
,它接受任意数量的参数,随后处理每个参数,同时维护该参数的位置索引:
template<int index, typename T>
void foo_impl(T value)
{
// Do something with index/value
}
template<int index, typename T, typename... Rest>
void foo_impl(T value, Rest... values)
{
// Do something with index/value
// Recursively handle remaining arguments
foo_impl<index + 1>(values...);
}
template<typename... T>
void foo(T... args)
{
foo_impl<1>(args...);
}
int main()
{
foo("test", 42);
}
这递归地实例化函数模板,直到它到达采用单个参数的基本模板。 foo_impl
的每个函数模板实例化都省略了模板类型参数。虽然这 compiles with Clang, GCC, and MSVC,但我不确定这是否合法。
如代码示例所示,省略模板参数是否合法?如果有,具体规则是什么?这些规则在 C++ 标准之间有变化吗?
具体规则在[temp.arg.explicit]
3 Trailing template arguments that can be deduced or obtained from default template-arguments may be omitted from the list of explicit template-arguments. A trailing template parameter pack not otherwise deduced will be deduced to an empty sequence of template arguments. If all of the template arguments can be deduced, they may all be omitted; in this case, the empty template argument list
<>
itself may also be omitted. In contexts where deduction is done and fails, or in contexts where deduction is not done, if a template argument list is specified and it, along with any default template arguments, identifies a single function template specialization, then the template-id is an lvalue for the function template specialization.
由于类型参数是尾随的,并且可以从函数调用的参数中推导出来,因此可以省略它们。
迄今为止的所有标准修订版中都存在这样的措辞(除了关于参数包的部分,C++03 中没有)。