我可以将模板参数传递给对象的成员函数,但不能传递给对象本身。
这可能吗?
#include <iostream>
#include <string>
using namespace std;
class Logger {
public:
Logger& operator()(int t) {
cerr << "(tag " << t << ") ";
return *this;
}
Logger& operator<<(const string &s) {
cerr << s << endl;
return *this;
}
template<int t> Logger& Tag() {
cerr << "(tag " << t << ") ";
return *this;
}
Logger() {}
template<int t> Logger() {
cerr << "(tag " << t << ") ";
}
};
int main() {
{
Logger log;
log(2) << "World";
log(3) << "World";
log.Tag<2>() << "Template 1";
log<2> << "Template 2"; // <-- error
}
}
这是错误消息(来自 GCC 13.2):
error: invalid operands to binary expression ('Logger' and 'int')
log<2> << "Template 2";
~~~^~
我想要实现的是让 log<2> 和 log.Tag<2> 以相同的方式运行。
实现
log<i> << ...
语法的唯一方法是使 log
成为变量模板。请注意,这会破坏 log << ...
和 log.Foo()
语法。
#include <iostream>
#include <string>
class Logger
{
int loglevel = 0;
public:
Logger(int loglevel) : loglevel(loglevel) {}
Logger& operator<<(const std::string &s)
{
std::cerr << loglevel << "->" << s << '\n';
return *this;
}
};
template <int N> Logger log(N);
int main()
{
log<2> << "blah";
}
这将为您提供 N 个“记录器”,每个日志级别一个,因此它们可能应该保存指向单个底层记录器的指针。
总体而言我认为这不是一个好主意。首先,为了一点点语法糖付出了太多的努力。其次,在现代,您可能应该围绕
std::format
设计记录器,这意味着您最终会得到诸如 log(i, "format", args...)
之类的语法。