为什么std :: endl生成这个神秘的错误消息? [英] Why is std::endl generating this cryptic error message?

查看:194
本文介绍了为什么std :: endl生成这个神秘的错误消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我尝试编译以下代码,我得到以下编译器错误(见代码)。如果 std :: endl 被删除,它编译没有错误。 >

  #include< iostream> 
#include< sstream>
#include< utility>

命名空间详细信息
{
template< class T>
void print(std :: ostream& stream,const T& item)
{
stream<项目;
}

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)
//注意:候选函数不可行:需要3个参数,但提供了4个
{
std :: stringstream ss;
detail :: print(ss,std :: forward< Args>(args)...);
stream<< ss.rdbuf();
}

int main()
{
print(std :: cout,答案是,42,std :: endl);
//错误:没有匹配的函数调用'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 ::

 >  print(std :: cout,The answer is,42,std :: endl< char,std :: char_traits< char>> 

更新



我使用以下剥离代码来跟踪问题:

  #include< iostream> 

命名空间详细信息
{
template< class T>
void print(std :: ostream& stream,const T& item)
{
stream<项目;
}
}

int main()
{
// detail :: print(std :: cout,std :: endl);
detail :: print(std :: cout,std :: endl< char,std :: char_traits< char>>);
}


If I try to compile the following code I get the following compiler error (see code.) It compiles without error if std::endl is removed.

#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 is a function template. When it is used, its template parameters have to be explicitly specified or deduced by the compiler.

std::ostream has an overload:

basic_ostream<charT,traits>& operator<<(
    basic_ostream<charT,traits>& (*pf) (basic_ostream<charT,traits>&) );

When we use

std::cout << std::endl;

the compiler deduces the types to be used for std::endl. Since you don't have the ability to fall back on automatic type deduction when calling print, you have to be explicit about which version of std::endl you want to use.

The following should work:

print(std::cout, "The answer is ", 42, std::endl<char, std::char_traits<char>>);

Update

I used the following stripped down code to track the issue:

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

这篇关于为什么std :: endl生成这个神秘的错误消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆