[英]Why is std::endl generating this cryptic error message?
如果我尝试编译以下代码,我会得到以下编译器错误(请参阅代码。)如果删除了std::endl
它将编译而不会出错。
#include <iostream>
#include <sstream>
#include <utility>
namespace detail
{
template <class T>
void print(std::ostream& stream, const T& item)
{
stream << item;
}
template <class Head, class... Tail>
void print(std::ostream& stream, const Head& head, Tail&&... tail)
{
detail::print(stream, head);
detail::print(stream, std::forward<Tail>(tail)...);
}
}
template <class... Args>
void print(std::ostream& stream, Args&&... args)
//note: candidate function not viable: requires 3 arguments, but 4 were provided
{
std::stringstream ss;
detail::print(ss, std::forward<Args>(args)...);
stream << ss.rdbuf();
}
int main()
{
print(std::cout, "The answer is ", 42, std::endl);
//error: no matching function for call to 'print'
}
std::endl
是一个函数模板。 使用它时,必须由编译器显式指定或推导其模板参数。
std::ostream
有一个重载:
basic_ostream<charT,traits>& operator<<(
basic_ostream<charT,traits>& (*pf) (basic_ostream<charT,traits>&) );
当我们使用
std::cout << std::endl;
编译器推断出用于std::endl
的类型。 由于您在调用print
时无法依靠自动类型推导,因此您必须明确要使用哪个版本的std::endl
。
以下应该有效:
print(std::cout, "The answer is ", 42, std::endl<char, std::char_traits<char>>);
更新
我使用以下精简代码来跟踪问题:
#include <iostream>
namespace detail
{
template <class T>
void print(std::ostream& stream, const T& item)
{
stream << item;
}
}
int main()
{
// detail::print(std::cout, std::endl);
detail::print(std::cout, std::endl<char, std::char_traits<char>>);
}
我认为这是因为如果传递函数模板,模板类型推导会失败。 它不能推断用于实例化endl
的参数。
请注意, endl
的定义是:
template <class charT, class traits>
basic_ostream<charT,traits>& endl (basic_ostream<charT,traits>& os);
更简单的例子:
template<class U> void func(U &u) { }
template<class T>
void print(const T &item) { }
int main()
{
print(func); // error: matching function for call to 'print(<unresolved overloaded function type>)'
}
您的错误消息是因为它尝试了各种方法来匹配您的函数调用参数包,但没有一个工作。
你可以通过自己定义一个简单的endl
来避免这个问题( Live Demo ):
constexpr struct endl_ {
friend std::ostream& operator << (std::ostream& os, const endl_&) {
os << '\n'; // << std::flush;
return os;
}
} endl;
template <class... Args>
void print(std::ostream& stream, Args&&... args)
{
std::stringstream ss;
std::initializer_list<int>{0, (void(ss << std::forward<Args>(args)), 0)...};
stream << ss.rdbuf();
}
int main()
{
print(std::cout, "The answer is ", 42, endl);
//error: no matching function for call to 'print'
print(std::cout, "The answer is NOT ", 13, endl);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.