【发布时间】:2015-06-20 03:31:53
【问题描述】:
我正在尝试在 C++ 中实现一个类来模仿 FORTRAN 中的 print 和 write 语句的语法。
为了实现这一点,我实现了一个类fooprint 并重载了fooprint::operator,(逗号运算符)。由于这个类应该打印到标准输出或文件,我还定义了两个宏:print(用于标准输出)和write(用于操作文件)。
我在尝试使用 write(data) a; 时遇到编译错误(请参阅下面的错误日志)。 如何获得具有上述属性的有效write 语句?
这是代码(Live Demo):
#include <iostream>
#include <fstream>
class fooprint
{
private:
std::ostream *os;
public:
fooprint(std::ostream &out = std::cout) : os(&out) {}
~fooprint() { *os << std::endl;}
template<class T>
fooprint &operator, (const T output)
{
*os << output << ' ';
return *this;
}
};
#define print fooprint(), // last comma calls `fooprint::operator,`
#define write(out) fooprint(out),
int main()
{
double a = 2.0;
print "Hello", "World!"; // OK
print "value of a =", a; // OK
print a; // OK
std::ofstream data("tmp.txt");
write(data) "writing to tmp"; // compiles with icpc; it doesn't with g++
write(data) a; // this won't compile
data.close();
return 0;
}
以及编译信息:
g++ -Wall -std=c++11 -o print print.cc
error: conflicting declaration ‘fooprint data’
#define write(out) fooprint(out),
^
note: in expansion of macro ‘write’
write(data) a;
^
error: ‘data’ has a previous declaration as ‘std::ofstream data’
error: conflicting declaration ‘fooprint a’
write(data) a;
^
error: ‘a’ has a previous declaration as ‘double a’
icpc -Wall -std=c++11 -o print print.cc
error: "data" has already been declared in the current scope
write(data) a;
error: "a" has already been declared in the current scope
write(data) a;
【问题讨论】:
-
在
out周围再放一对大括号(即fooprint((out))或fooprint{out}),这样它就构成了一个临时声明而不是变量声明。 -
:o 它与大括号一起使用:
fooprint({out})。如果我不使用 c++11 怎么办? -
我的错误,
fooprint((out))应该是(fooprint(out))。这应该适用于任何版本的 C++。 -
完美!谢谢。你从哪里学到的这个“技巧”? :o
-
我是从几年前看到的评论中了解到的。现在你学会了! :)