使用友元函数从多态类中检索类型信息
Using friend functions to retrieve type information from a polymorphic class?
我有一个关于在嵌套多态类中使用友元函数来检索类型信息的问题。
下面的代码演示了我正在做的事情。给定两个类A<T>
和B<T>
,我可以创建一个包含A
或B
的运行时多态包装器。在实践中,这个包装器可以容纳任何东西,包括另一个具有类似静态接口的模板化类。
template<typename T>
struct A {
T value_;
A(T value) : value_(value) {}
void sayHello() const {
std::cout << "Hello from A! " << value_ << 'n';
}
};
template<typename T>
struct B {
T value_;
B(T value) : value_(value) {}
void sayHello() const {
std::cout << "Hello from B! " << value_ << 'n';
}
};
包装器来自SeanPrent的Runtime多态性概念,但我需要检索一些操作的类型信息。例如,也许我可以添加A
和B
,但不能添加A
和C
。基本上,如果我在模板化包装器类中放置一个友元函数,我就可以将对象强制转换回其原始类型。
class Wrapper {
private:
class Concept {
public:
virtual ~Concept() = default;
virtual void sayHello() const = 0;
};
template<typename T>
class Model final
: public Concept {
private:
T data_;
public:
Model(T data) : data_(data) {}
virtual void sayHello() const override {
data_.sayHello();
}
private:
template<typename U>
friend inline void doSomething(const Concept &lhs, const B<U> &rhs) {
T x = static_cast<const Model<T> &>(lhs).data_;
x.sayHello();
rhs.sayHello();
auto y = x.value_ + rhs.value_;
std::cout << y << 'n';
}
};
template<typename U>
friend inline void doSomething(const Concept &lhs, const B<U> &rhs);
std::shared_ptr<const Concept> ptr_;
public:
template<typename T>
explicit inline Wrapper(T a)
: ptr_(std::make_shared<Model<A<T>>>(std::move(a))) {}
template<typename U>
friend inline void someFriend(Wrapper &lhs, B<U> &rhs) {
doSomething(*lhs.ptr_, rhs);
}
};
注意,我能够在友元函数中static_cast
Concept
类,因为它的类型可以从Model<T>
类的上下文中推导出来。
所以我可以使用这样的代码:
Wrapper a(1);
B<int> b{2};
someFriend(a, b);
哪个输出:
Hello from A! 1
Hello from B! 2
3
我的问题是,以这种方式做事是否存在某种无法预见的问题。此外,如果我替换指针中的对象,static_cast
是否仍然有效?
我运行的一些初步测试表明它相当可靠,但我偶尔会遇到这样的问题,即调用似乎围绕第一个对象"专门化",然后如果指针变为新对象,就不会切换。
这是代码的链接。
您违反了ODR(一个定义规则),因此您的代码格式不正确,不需要诊断。
具体而言:
template<typename U>
friend inline void doSomething(const Concept &lhs, const B<U> &rhs);
对此有不止一个定义;事实上,每个Model<T>
都有一个。ODR对此必须有一个定义。
格式错误,无需诊断(IL-NDR)是C++标准领域中最糟糕的事情。
您看到的症状是调用了一些随机实现,并且"卡住"了。没有发生任何安全的事情。
相关文章:
- 如何在 C++17 中检索 std::filesystem::file_time_type 的时钟类型
- 如何从C 中的集合中检索多个继承类型
- 检索不同类型的对象指针
- 自动检索返回类型的模板功能
- 从保存变量数据类型的数据结构中检索值,而不指定返回类型
- 为什么C++模板类型匹配不检索引用限定符"&"?
- 使用友元函数从多态类中检索类型信息
- 从未知dll(c++)中检索函数(名称、返回类型、参数)
- 如何检索要在模板中使用的函数的返回类型
- 如何从概念中检索类型?
- cpp函数来检索各种数据类型的值
- 从数据库中以 blob 数据类型形式存储的原始图像数据中检索 CImage 对象
- std::用户定义类型的映射在检索值时会使程序崩溃
- 在编译时检索 Opencv Mat_的类型<T>
- ArgumentError 在 Boost.Python 中的类中存储和检索指针:错误的类型
- 根据对象的类型从矢量中检索对象
- 从 std::type_info 检索数据类型的大小
- 从 c++ 检索 Python 类型
- 仅检索对象的类型
- 无法从C++代码中检索正确的字符串.是否有一种通用类型用于处理c#上的无符号字符*