crtp 相关问题

奇怪的重复模板模式(CRTP)是一种C ++习语,其中类X派生自使用X本身作为模板参数的类模板实例化。

在简单的 CRTP 案例中没有名为“XXX”的成员

这里我有一个简单的CRTP案例: #包括 #包括 模板 班级基础 { constexpr 静态 size_t impl_num = Impl::num; }; 模板 这里我有一个简单的CRTP案例: #include <cstddef> #include <utility> template <typename Impl> class base { constexpr static size_t impl_num = Impl::num; }; template <typename Impl> class deriv : public base<deriv<Impl>> { friend class base<deriv<Impl>>; constexpr static size_t num = Impl::num_in; }; class actual_impl { public: constexpr static size_t num_in = 10; }; using my_type = deriv<actual_impl>; int main() { my_type a{}; } 这个片段编译得很好,但是当我将基类更改为: #include <cstddef> #include <utility> template <typename Impl> class base { constexpr static std::make_index_sequence<Impl::num> idx{}; }; template <typename Impl> class deriv : public base<deriv<Impl>> { friend class base<deriv<Impl>>; constexpr static size_t num = Impl::num_in; }; class actual_impl { public: constexpr static size_t num_in = 10; }; using my_type = deriv<actual_impl>; int main() { my_type a{}; } Clang 抱怨error: no member named 'num' in 'deriv<actual_impl>'。我只是很困惑为什么第一种情况有效但第二种情况不起作用,这两种情况之间的根本区别是什么,因为在我看来,在这两种情况下 Impl::num_in 都在基类中使用。 一般来说,基类是否可以使用 Impl 中的 typedef 或 constexpr? 根本的区别是当您尝试访问 Impl 类的内部时。 Impl中的base<Impl>是一个不完整的类型,并且你可以用它做什么有一定的限制。 特别是,您无法访问 num 内的 base 数据成员,这就是该行的原因 constexpr static std::make_index_sequence<Impl::num> idx{}; 导致编译错误。请注意,要定义 base 类,编译器必须知道当时 Impl::num 的值。 与此相反,在第一个示例中,Impl::num仅用于初始化impl_num的值,否则不依赖于Impl::num。该初始化的实例化稍后发生,当 Impl 成为完整类型时。因此,没有错误。 如果稍微改变一下定义, template<typename Impl> class base { constexpr static decltype(Impl::num) impl_num = Impl::num; // or constexpr static auto impl_num = Impl::num; } 并使 impl_num type 依赖于 Impl,你会因为同样的原因得到同样的错误。 添加间接没有帮助,以下代码也无法编译: template<typename Impl> class base { constexpr static size_t impl_num = Impl::num; constexpr static std::make_index_sequence<impl_num> idx{}; }; 一般来说,基类是否可以使用 Impl 中的 typedef 或 constexpr? 这要看情况。您只能在 Impl 是完整类型时发生实例化的上下文中使用它们。例如, template<typename Impl> class base { public: void foo() { decltype(Impl::num) impl_num = 0; } }; 很好,但是 template<typename Impl> class base { public: decltype(Impl::num) foo() { return 0; } }; 不是。 避免 CRTP 中不完整类型潜在问题的标准技巧是引入辅助特征类: // Just forward declarations template<typename Impl> class deriv; class actual_impl; using my_type = deriv<actual_impl>; template<class> struct traits; template<> struct traits<my_type> { using num_type = std::size_t; }; template <typename Impl> class base { public: typename traits<Impl>::num_type foo() { return 0; } }; // Now actual definitions // ... 在这里,要访问 traits<Impl> 内部结构,Impl 不必是完整类型。

回答 1 投票 0

C++11:在类中查找方法和错误:嵌套名称说明符中使用的类型不完整

使用 C++11 中的 CRTP 习惯用法,我试图检查派生类是否具有名为 size 的方法。 #包括 模板 结构 IsContainer { 模板<

回答 1 投票 0

CRTP 子级定义父级使用的类型

我有一个 CRTP 层次结构,其中子级定义了父级使用的类型,但该类型具有对父级的回调: 模板类回调> 类别选项1 {...

回答 1 投票 0

CRTP 设计,其中基类实例化派生类指定的类型的成员

正如 Evg 的 crtp-pass-types-from-driven-class-to-base-class 中所述,编译器无法推导出 Base 类声明中的类型 Impl::TType: 模板 结构...

回答 1 投票 0

为什么 CRTP 在以下函数中不起作用?

我正在学习CRTP C++模式 我的代码 模板 类基序{ 民众: void sendOrder() {static_cast(this)->send();} 无效发送(){cout<< "S...

回答 1 投票 0

为什么 CRTP 在我的函数中不起作用?

我正在学习CRTP C++模式 我的代码 模板 类基序{ 民众: void sendOrder() {static_cast(this)->send();} 无效发送(){cout<< "S...

回答 2 投票 0

为什么CRTP无法正常工作?

我正在学习CRTP C++模式 我的代码 模板 类基序{ 民众: void sendOrder() {static_cast(this)->send();} 无效发送(){cout<< "S...

回答 2 投票 0

CRTP 家长无法访问祖父母

#包括 #包括 模板 类动物 { 民众: std::字符串打印() { 返回 static_cast(this)->

回答 1 投票 0

如何让 MSVC 在 c++20 编译时查看静态 constexpr 成员变量和函数?

背景 我试图在编译时在 CRTP 类中访问 constexpr 变量。下面是一个 MVCE。 模板 结构体CRTP { 静态 constexpr int get_va...

回答 1 投票 0

调用存储在std::any中的对象的成员函数

假设我有一个模板类,如下所示: 模板 我的班级 { 民众: MyClass(std::string const& 名称){ s = 姓名; } T return_var1() {...

回答 1 投票 0

子类中部分特化父方法

我有一个模板类,我想专门针对许多不同的类型。就像是: #包括 #包括 #包括 // 允许静态为...

回答 1 投票 0

虚拟基类的模板化编译时版本可以作为接口吗?

我正在开发基于模型的系统工程(MBSE)的框架。在此,我有一个名为 Bridge 的构造。桥接器可以从一个电子设备发送信号(异步调用)和/或操作(同步调用)...

回答 1 投票 0

何时在 c++23 中使用 CRTP 代替显式对象参数?

问题的简短版本 C++23 为我们提供了一种编写 mixin 类的新方法(而不是 CRTP)。在什么情况下 CRTP 仍会受到青睐? 两种方法的总结 CRTP 很强大

回答 1 投票 0

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

这是真实代码的片段,但想法是我想在日志中打印服务类型。 在此示例中,我尝试打印它,但出现异常,但我不知道为什么。 我还有其他的

回答 1 投票 0

CRTP 基类有没有办法访问派生类中的类型?

我正在尝试从 CRTP 基内部访问派生类类型,例如: 模板 基类{ 使用 Type = 类型名称 CRTP::Type; void 方法(const Type& t) {

回答 1 投票 0

在 std::vector 上调用 Push_back 时出现分段错误

下面我提供了我收到的错误的最小工作示例。在较高级别上,应用程序分段错误发生在我尝试将 Point 对象推回到 ve 的行...

回答 1 投票 0

C++ 中静态和动态多态性的代码?

我尝试在需要擦除的基础上实现适合动态和静态多态性的类,即仅在必须时才使用动态多态性(例如异构列表)。我写以下...

回答 1 投票 0

P0847 推论 - 它可以允许通用克隆而不需要 CRTP 吗?

P0847 提出了对成员函数使用显式 this 参数的可能性。 除了该提案带来的其他好处之外,没有 C 的 CRTP 还具有巨大的新可能性......

回答 2 投票 0

CRTP 在 std::hash 的基类方面为派生类提供专业化

TLDR 我正在尝试根据 CRTP 样式框架中的基类为一堆派生类编写一次模板专门化。但是,我无法编译它。 我正在尝试什么...

回答 1 投票 0

从模板参数中嵌套的类模板继承[重复]

我有一个特征类,它指定类层次结构的基类和派生类。我试图从嵌套在特征类中的类模板继承。 这是一个小例子: 圣殿...

回答 1 投票 0

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