在C ++中调用函数时,会写入函数的名称,然后是()
,以将其区分为函数调用。为什么我不能以同样的方式调用流操纵函数?
为什么不允许这样做?:
cout << "Hello!" << endl();
不是endl
变量持有\n
?
谢谢!
答案 0 :(得分:2)
操纵器是专门设计用于与流对象上的插入(&lt;&lt;&lt;&lt;&quot;&)和提取(&gt;&gt;)运算符结合使用的函数,例如:
cout << boolalpha;
它们仍然是常规函数,也可以使用流对象作为参数调用为任何其他函数,例如:
boolalpha (cout);
因此,在您的代码中,您可以执行
cout << "Hello!";
endl(cout);
而不是
cout << "Hello!" << endl;
答案 1 :(得分:2)
流操纵器是功能。因此,可以使用调用运算符()
调用 。以下是您在广告联盟中呼叫std::endl
的方法:
std::endl(std::cout);
这是必须为您要使用的每个流std::endl
调用的方式。这是因为std::endl
是一个返回对流对象的引用的函数。这是一种非常古怪的方式,所以有一个方便的功能来简化语法:
std::ostream& operator<<(std::ostream& (*manip)(std::ostream&));
这是operator<<()
的重载,它的左侧是一个流,右侧是一个操纵器。 std::endl
在技术上是一个函数,因此可以将其转换为函数指针。
在这个重载的实现中,manip
几乎被我调用了。这允许语法如:
std::cout << "Hello, World" << std::endl;
如果你继续使用call运算符调用std::endl
,它将返回对流的引用。还有另一个operator<<()
重载,它以const void*
为参数。那将是无意中被称为的过载。
std::cout << std::endl(std::cout); // prints a newline then an address
答案 2 :(得分:1)
不是一个持有\ n?
的变量
不,不是。 std::endl
是全局命名空间
template<typename _CharT, typename _Traits>
inline basic_ostream<_CharT, _Traits>&
endl(basic_ostream<_CharT, _Traits>& __os)
{ return flush(__os.put(__os.widen('\n'))); }
在表达式std::cout << endl_or_something
中,<<
的右侧是对operator<<
的调用的参数(第一个参数是std::ostream
隐式)。所以endl_or_something应该是int,double或其他类型,可以转换为operator<<
的可能参数之一。这个运算符的重载版本带有指向函数的指针(引用std::ostream
的函数并返回对std::ostream
的引用):
// [27.6.2.5] formatted output
// [27.6.2.5.3] basic_ostream::operator<<
//@{
/**
* @brief Interface for manipulators.
*
* Manipulators such as @c std::endl and @c std::hex use these
* functions in constructs like "std::cout << std::endl". For more
* information, see the iomanip header.
*/
__ostream_type&
operator<<(__ostream_type& (*__pf)(__ostream_type&))
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 60. What is a formatted input function?
// The inserters for manipulators are *not* formatted output functions.
return __pf(*this);
}
由于std::endl
签名匹配,因此可以在表达式
std::cout << "Hello!" << std::endl;
或等效
std::cout << "Hello!";
std::endl( std::cout);
但是请注意,当需要简单的换行符时,通常会错误地使用此操纵器,从而导致缓冲性能较差。在这种情况下,只使用"\n"
。
为什么不允许这样做?:
cout << "Hello!" << endl();
std :: endl接受一个参数std :: ostream。您可以看到它可以通过以下方式调用:
return __pf(*this);
表示
return std::endl( *this); // std::endl( std::cout);
没有 std::endl
的版本不带参数,因此可以使用
std::endl()
在表达
中std::cout << std::endl;
它表示operator<<
的参数,它作为指向函数的指针传递,然后在operator<<
的正文中调用。