检查参数是否存在的 C++ 概念不起作用

C++ concept that checks if parameter present doesn't work

我的项目中有一些 class 层次结构:

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 检查 returns true,但首先检查 returns false

不要觉得这可能是个问题,但是所有classes都标记为__declspec(dllexport)并且Material也继承了一些Object class


更新:

好吧,我认为这是因为在其他 class 我写了

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 个模块:EngineGame。所有这些代码都来自引擎模块,它在 Engine 中工作,但是当我 link 它是 dll 到 Game 时它不起作用。此外,Game 模块中的 static_assert(CanEnableShared<Material3D>) 没有效果,概念匹配,但是当我跟踪上面的构造函数时,它绕过了我的 constexpr。概念有一些 dll-specific 行为吗?或者对于 constexpr?我怀疑,它与 objects 的编译方式和 linked

有某种关系

在使用 Shared<Material3D>Game 中的 header 之上添加 #include "Engine/Material3D.h" 解决了问题,但这不是我想要的。看起来我必须在我引用的 header 中包含每个 class 的 header,前向声明在这种情况下不起作用


前向声明似乎只有在同一个模块中出现时才会被正确检查

{ expr } -> concept中,expr的类型是determined as if by decltype((expr))

decltype((T::last_valid_counter))uint64 *&,所以这就是您需要传递给 std::same_as.

的内容

有趣的是,Clang 似乎有一个错误,因为它似乎使用了 decltype(expr)