C++ C++;带有自定义初始化的静态分派
我想将CRTP用于代码中对性能敏感的部分。但是,我的基类有一个位集,其大小取决于派生类。我希望这样的事情能奏效:C++ C++;带有自定义初始化的静态分派,c++,static,bitset,dispatch,crtp,C++,Static,Bitset,Dispatch,Crtp,我想将CRTP用于代码中对性能敏感的部分。但是,我的基类有一个位集,其大小取决于派生类。我希望这样的事情能奏效: template <typename Derived> class Base { protected: std::bitset<Derived::bsize> data_; }; class Foo : public Base<Foo> { public: constexpr static size_t bsize = 2; };
template <typename Derived>
class Base {
protected:
std::bitset<Derived::bsize> data_;
};
class Foo : public Base<Foo> {
public:
constexpr static size_t bsize = 2;
};
模板
阶级基础{
受保护的:
std::位集数据;
};
Foo类:公共基础{
公众:
constexpr静态大小=2;
};
但编译器抱怨:“Foo中没有成员bsize”。我想我也可以通过在基类中模板化位集长度来解决我的问题:
template <typename Derived, size_t size>
class Base {
protected:
std::bitset<size> data_;
};
class Foo : public Base<Foo,2> { ... };
模板
阶级基础{
受保护的:
std::位集数据;
};
Foo类:公共基{…};
将来,我可能希望使用更复杂的表达式来计算位集长度。有没有办法使用constexpr函数完成任务?(精神上更接近我的第一个非工作解决方案)
谢谢。 < P>答案是:C++中不能用CRTP来实现这一点。当
Base
被实例化时,Foo::bsize
还不存在。这是因为编译器在Foo
类上看到Base
时会发生这种情况,它位于{
之前
这里有一个解决方法可以实现您想要的功能,即将所有必要的信息捆绑在一个类中,然后将其作为模板参数提供。我不知道此模式的名称(我见过“baggage class”,但这感觉有些贬义),但您可以在标准库中找到此类示例,例如
class脚踏板{
constexpr静态大小=2;
};
模板
类BasicFoo{
受保护的:
std::位集数据;
};
Traits非常灵活——您只需将static constexpr
函数放入FooTraits
中,即可计算所需的任何内容。在您的情况下,派生类将FooTraits
的派生类型特定版本传递给BasicFoo
的Traits
模板参数
值得注意的是,你的理解可能会有所不同。虽然灵活,但traits的问题在于,想要实现FooTraits
概念的人需要确保他们实现了BasicFoo
所需的所有东西,否则他们会遇到可怕的编译错误(在C++20中,这是通过.如果不仔细考虑,特性可能会成为一个垃圾场,这使得实现另一种FooTraits
更加困难
class FooTraits {
constexpr static size_t bsize = 2;
};
template <class Traits = FooTraits>
class BasicFoo {
protected:
std::bitset<Traits::bsize> data_;
};