简体   繁体   中英

Misunderstanding variadic templates and template type deduction

I'm compiling with C++17 with code similar to this sample:

#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;

}

What I've discovered is template type deduction fails when I apply Args... to the template parameter list of both ostream_type and ostreambuf_iterator_type , but it would be fine if I assigned the char_type and the traits_type from the ostream_type .

typename ostreambuf_iterator_type = ::std::ostreambuf_iterator<typename ostream_type::char_type, typename ostream_type::traits_type>>

Why is this, when the template parameters to ::std::basic_ostream and ::std::ostreambuf_iterator are the same?

Template argument deduction tries to deduce ostream_type from the function argument. In doing so it is not bound by the default argument you provided. Rather the default argument is simply ignored.

ostream_type will be deduced to std::basic_ostream<char> .

Then there is nothing left depending on Args in the function parameters and the parameter pack is deduced to be empty.

The empty Args is then expanded into the default argument ostreambuf_iterator_type =::std::ostreambuf_iterator<Args...> , which fails because std::ostreambuf_iterator needs at least one template argument.

If you want Args to be deduced as the template arguments to the std::basic_ofstream passed to your function, you need to constraint template argument deduction in the parameter:

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;
}

Now the deduction has to deduce Args as the template arguments of os .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM