从正在实例化的 crtp 类型打印字符串

Print string from crtp type being instanciated

提问人:eniac 提问时间:10/12/2023 更新时间:10/12/2023 访问量:62

问:

这是真实代码的片段,但想法是我想在我的日志中打印服务类型。 在这个例子中,我试图打印它,但我得到了一个异常,我不知道为什么。 我还有其他使用编译时多态性的方法,这些方法工作正常。

template <typename servicetype> class Service {
public:
        std::string& service_type() { return static_cast<servicetype*>(this)->service_type_impl(); }

};

class ServiceType1 : public Service<ServiceType1> {
public:
    ServiceType1() :service_type_("Service Type 1") {}
    std::string& service_type_impl() { return service_type_; }
private:
    std::string&& service_type_;
}; 

class ServiceType2 : public Service<ServiceType2> {
public:
    ServiceType2() :service_type_("Service Type 2") {}
    std::string& service_type_impl() { return service_type_; }
private:
    std::string&& service_type_;
}; 

template <typename T>
class Server
{
public:
    void print() {
        std::cout << service_.service_type()<<std::endl;
    }

    Service<T> service_;
}; 

 
int main()
{

    Server<ServiceType1> service_type1;
    Server<ServiceType2> service_type2;

    service_type1.print();
    service_type2.print();

}
C++ CRTP 静态多态性

评论

0赞 Yksisarvinen 10/12/2023
你想用这个右值参考做什么?
0赞 eniac 10/12/2023
@YksisarvinenInitially我在构造函数中使用右值,以避免字符串复制
0赞 Louis Go 10/12/2023
如果您要返回静态存储,为什么不直接返回呢?我认为在您的用例中,在编译时是已知的。std::string_view service_type_impl(){return "Service Type X";}Service Type X

答:

3赞 Damir Tenishev 10/12/2023 #1

从不构造实现类 ServiceType1 和 ServiceType2 的对象。

仅构造 Server 和 Service 类对象。

可能的选项之一是:

template <typename servicetype> class Service {
public:
    std::string& service_type() { 
        servicetype* pimpl = new servicetype;
        return pimpl->service_type_impl(); 
    }
};

但这完全取决于你想实现什么。

而且你需要更换

std::string&& service_type_;

std::string service_type_;

在两个派生类中,以便此变量可以真正复制传递的字符串。

评论

0赞 Yksisarvinen 10/12/2023
很好,这就是为什么 CRTP 类不应该有构造函数的原因。public
0赞 eniac 10/12/2023
谢谢@Damir Tenishev。我检查了 omther 方法,并意识到此 servicetype 类没有成员变量。只有方法。这就是为什么我之前没有收到错误的原因。