如何将模板参数传递给对象而不调用其成员函数?

问题描述 投票:0回答:1

我可以将模板参数传递给对象的成员函数,但不能传递给对象本身。
这可能吗?

#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> 以相同的方式运行。

c++ object templates
1个回答
0
投票

实现

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...)
之类的语法。

© www.soinside.com 2019 - 2024. All rights reserved.