c++ - 如何在编译时从范围运算符中提取类型?
问题描述
是否有可能(不使用宏)在不带参数的静态函数中由编译器推导出模板参数?
struct Widget
{
template<typename T = ?>
static void foo()
{
}
};
struct Base : Widget {};
struct Derived : Base {};
Base::foo(); // T should be deduced as Base
Derived::foo(); // T should be deduced as Derived
在我的用例中,编写Base::foo<Base>();
不仅是多余的(编译器已经拥有该信息,正如我已经说过的那样Base::
),而且还会引入出错的可能性——Base::foo<SomeOtherType>();
应该禁止调用。
有没有办法在编译时区分 foo 被称为 asBase::foo()
还是 as Derived::foo()
?
解决方案
此问题的答案中概述了像这样的多级 CRTP 层次结构的一种方法。
另一种方法是每隔一层注入基类。
#include <iostream>
#include <typeinfo>
class WidgetBase
{
};
template <class D, class B = WidgetBase>
class Widget : public B
{
public:
static void foo()
{
std::cout << typeid(D).name() << " is " << sizeof(D) << " bytes large\n";
}
};
class Base : public Widget<Base> { int a; };
class Derived : public Widget<Derived, Base> { int b; };
class MoreDerived : public Widget<MoreDerived, Derived> { };
int main()
{
Base::foo();
Derived::foo();
MoreDerived::foo();
}
推荐阅读
- arrays - Mule 4 dataweave 2.0 映射嵌套数组逻辑
- java - 如何让 SLF4J 用于我的 IntelliJ 项目?
- azure - 使用 Microsoft.Identity.Client 在 android 上进行身份验证问题
- pgadmin-4 - pgAdmin 4 覆盖不会关闭
- tensorflow - TFLiteConverter.from_saved_model RuntimeError:在 SavedModel 中找不到与标签 {'serve'} 关联的 MetaGraphDef
- typescript - 如何使用打字稿在vue类样式组件中双向绑定v-model对象
- javascript - 如何将多个按钮数据传递给 1 个查询
- javascript - 如何使用 javascript 显示隐藏/显示菜单?
- python - 将字符串保存在 ast.literal_eval 到 dict
- c - C预处理器为多种类型赋值