【发布时间】:2021-07-11 06:35:08
【问题描述】:
我的项目中有一些类层次结构:
template<typename T>
class __declspec(dllexport) EnableSharedFromThis
{
public:
...
uint64* last_valid_counter = nullptr;
};
class __declspec(dllexport) Material : public Object, public EnableSharedFromThis<Material>
{
...
}
class __declspec(dllexport) Material3D : public Material
{
...
}
我有一个概念
template<typename T>
concept CanEnableShared = requires
{
{ T::last_valid_counter } -> std::same_as<uint64*>;
};
但是当我这样做时
auto a = CanEnableShared<Material3D>;
auto b = CanEnableShared<Material>;
auto c = CanEnableShared<EnableSharedFromThis<Material>>;
我得到了false 三次。我做错了什么?
更新:
将我的概念改为:
template<typename T>
concept CanEnableShared = requires
{
{ T::last_valid_counter } -> std::same_as<uint64*&>;
};
现在 2 和 3 次检查返回 true,但第一次检查返回 false
不要认为这可能是个问题,但是所有的类都标记为__declspec(dllexport) 并且Material 也继承了一些Object 类
更新:
好的,我认为这是因为我在其他课程中写的
Shared(T* ptr) requires CanEnableShared<T>
: ptr_(ptr)
, counter_(new uint64(1))
{
ptr->last_valid_counter = counter_;
}
Shared(T* ptr)
: ptr_(ptr)
, counter_(new uint64(1))
{
}
应该简化成什么
Shared(T* ptr)
: ptr_(ptr)
, counter_(new uint64(1))
{
if constexpr (CanEnableShared<T>)
{
ptr->last_valid_counter = counter_;
}
}
Shared<T> 是我自己的 std::shared_ptr<T> 模拟
你好!
我的项目中有 2 个模块:Engine 和 Game。所有这些代码都来自引擎模块,它在Engine 中工作,但是当我将它的dll 链接到Game 时它不起作用。此外,Game 模块中的static_assert(CanEnableShared<Material3D>) 没有效果,概念匹配,但是当我追踪到上面的构造函数时,它绕过了我的 constexpr。概念是否有一些特定于 dll 的行为?还是为 constexpr?我怀疑,它在某种程度上与对象的编译和链接方式有关
在使用Shared<Material3D> 的Game 内的标题顶部添加#include "Engine/Material3D.h" 可以解决问题,但这不是我想要的。看起来我必须在我引用的标题中包含我引用的每个类的标题,在这种情况下前向声明不起作用
前向声明似乎只有在它们出现在同一个模块中时才被正确检查
【问题讨论】:
标签: c++ c++20 c++-concepts