对可变参数模板和模板类型推导的误解
Misunderstanding variadic templates and template type deduction
我正在使用 C++17 进行编译,代码类似于此示例:
#include <iostream>
#include <iterator>
class Foo {};
template <typename... Args,
typename ostream_type = ::std::basic_ostream<Args...>,
typename ostreambuf_iterator_type = ::std::ostreambuf_iterator<Args...>>
ostream_type &operator<<(ostream_type &os, const ::Foo f) {
// Do ostreambuf_iterator_type stuff with 'f' here...
return os;
}
int main() {
::Foo f;
::std::cout << f;
return 0;
}
我发现当我将Args...
应用于ostream_type
和ostreambuf_iterator_type
的模板参数列表时模板类型推导失败,但如果我赋值就没问题来自 ostream_type
.
的 char_type
和 traits_type
typename ostreambuf_iterator_type = ::std::ostreambuf_iterator<typename ostream_type::char_type, typename ostream_type::traits_type>>
为什么 ::std::basic_ostream
和 ::std::ostreambuf_iterator
的模板参数相同?
模板参数推导试图从函数参数推导ostream_type
。这样做时,它不受您提供的默认参数的约束。相反,默认参数被简单地忽略了。
ostream_type
将推导为 std::basic_ostream<char>
.
那么函数参数中依赖Args
的东西就没有了,推导出参数包为空
然后将空的 Args
扩展为默认参数 ostreambuf_iterator_type = ::std::ostreambuf_iterator<Args...>
,但失败了,因为 std::ostreambuf_iterator
至少需要一个模板参数。
如果你想把Args
推导为传给你的函数的std::basic_ofstream
的模板实参,你需要在参数中限制模板实参推导:
template <typename... Args,
typename ostreambuf_iterator_type = ::std::ostreambuf_iterator<Args...>>
auto &operator<<(::std::basic_ostream<Args...> &os, const Foo f) {
// Do ostreambuf_iterator_type stuff with 'f' here...
return os;
}
现在推导必须推导出 Args
作为 os
的模板参数。
我正在使用 C++17 进行编译,代码类似于此示例:
#include <iostream>
#include <iterator>
class Foo {};
template <typename... Args,
typename ostream_type = ::std::basic_ostream<Args...>,
typename ostreambuf_iterator_type = ::std::ostreambuf_iterator<Args...>>
ostream_type &operator<<(ostream_type &os, const ::Foo f) {
// Do ostreambuf_iterator_type stuff with 'f' here...
return os;
}
int main() {
::Foo f;
::std::cout << f;
return 0;
}
我发现当我将Args...
应用于ostream_type
和ostreambuf_iterator_type
的模板参数列表时模板类型推导失败,但如果我赋值就没问题来自 ostream_type
.
char_type
和 traits_type
typename ostreambuf_iterator_type = ::std::ostreambuf_iterator<typename ostream_type::char_type, typename ostream_type::traits_type>>
为什么 ::std::basic_ostream
和 ::std::ostreambuf_iterator
的模板参数相同?
模板参数推导试图从函数参数推导ostream_type
。这样做时,它不受您提供的默认参数的约束。相反,默认参数被简单地忽略了。
ostream_type
将推导为 std::basic_ostream<char>
.
那么函数参数中依赖Args
的东西就没有了,推导出参数包为空
然后将空的 Args
扩展为默认参数 ostreambuf_iterator_type = ::std::ostreambuf_iterator<Args...>
,但失败了,因为 std::ostreambuf_iterator
至少需要一个模板参数。
如果你想把Args
推导为传给你的函数的std::basic_ofstream
的模板实参,你需要在参数中限制模板实参推导:
template <typename... Args,
typename ostreambuf_iterator_type = ::std::ostreambuf_iterator<Args...>>
auto &operator<<(::std::basic_ostream<Args...> &os, const Foo f) {
// Do ostreambuf_iterator_type stuff with 'f' here...
return os;
}
现在推导必须推导出 Args
作为 os
的模板参数。