Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

C++ function strprint(expr, expr, expr…) almost works, but not quite, why?

Here’s a small C++ ‘strprint’ function that seems to mostly work:

#include <sstream>
#include <iostream>

// send_to_stream: send all arguments to the specified stream.
inline void send_to_stream(std::ostream &os) {}
template <typename ARG, typename... REST>
inline void send_to_stream(std::ostream &os, const ARG &arg, const REST & ... rest) {
    os << arg;
    send_to_stream(os, rest...);
}

// strprint: convert all arguments to a string by sending them to a stringstream.
template <typename... ARGS>
std::string strprint(const ARGS & ... args) {
    std::ostringstream oss;
    send_to_stream(oss, args...);
    return oss.str();
}

int main(int argc, char **argv) {
    std::string s1 = strprint("five:", 5, "\n");
    std::cout << "S1=" << s1 << "." << std::endl;

    // std::string s2 = strprint("five:", 5, std::endl);
    // std::cout << "S2=" << s1 << "." << std::endl;
};

This program, when run, produces the output:

five:5
.

which is exactly what I would expect. But when I uncomment the ‘s2’ lines, I get a compile error:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

foo.cpp: In function ‘int main(int, char**)’:
foo.cpp:25:53: error: too many arguments to function ‘std::string strprint(const ARGS& ...) [with ARGS = {}; std::string = std::__cxx11::basic_string<char>]’
   25 |      std::string s2 = strprint("five:", 5, std::endl);
      |                                                     ^
foo.cpp:15:13: note: declared here
   15 | std::string strprint(const ARGS & ... args) {
      |             ^~~~~~~~

This makes no sense. Too many arguments to a function that takes an unlimited number of arguments? It doesn’t seem to like passing ‘std::endl’ through a variadic list.
Why not? What am I missing?

>Solution :

std::endl is a function template:

template< class CharT, class Traits >
std::basic_ostream<CharT, Traits>& endl( std::basic_ostream<CharT, Traits>& os );

Admittedly, the error message is rather confusing. The problem is that the type of std::endl cannot be deduced, because you would need to instantitate the function first:

std::string s2 = strprint("five:", 5, std::endl<std::ostream::char_type,std::ostream::traits_type>);
std::cout << "S2=" << s1 << "." << std::endl;

Live Demo

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading