【问题标题】:C++ concept that checks if parameter present doesn't work检查参数是否存在的 C++ 概念不起作用
【发布时间】: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&lt;T&gt; 是我自己的 std::shared_ptr&lt;T&gt; 模拟

你好!

我的项目中有 2 个模块:EngineGame。所有这些代码都来自引擎模块,它在Engine 中工作,但是当我将它的dll 链接到Game 时它不起作用。此外,Game 模块中的static_assert(CanEnableShared&lt;Material3D&gt;) 没有效果,概念匹配,但是当我追踪到上面的构造函数时,它绕过了我的 constexpr。概念是否有一些特定于 dll 的行为?还是为 constexpr?我怀疑,它在某种程度上与对象的编译和链接方式有关


在使用Shared&lt;Material3D&gt;Game 内的标题顶部添加#include "Engine/Material3D.h" 可以解决问题,但这不是我想要的。看起来我必须在我引用的标题中包含我引用的每个类的标题,在这种情况下前向声明不起作用


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

【问题讨论】:

    标签: c++ c++20 c++-concepts


    【解决方案1】:

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

    decltype((T::last_valid_counter))uint64 *&amp;,所以这就是您需要传递给 std::same_as 的内容。

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

    【讨论】:

    • 这个错误似乎在trunk中得到了解决。
    • 它有效,但不完全。我更新了我的问题。我是否正确更新了我的概念?
    • @Espeon Can't reproduce。你能提供一个minimal reproducible example 它不起作用吗?还请告诉我们您的编译器、它的版本和标志。
    • 关于编译器 - 从命令行我看到 C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\bin\HostX86\x64\CL .exe /c /ZI /JMC /nologo /W3 /WX- /diagnostics:column /sdl /MP /Od /D _DEBUG /D ENGINE_EXPORTS /D _WINDOWS /D _USRDLL /D _CRT_SECURE_NO_WARNINGS /D _WINDLL /D _UNICODE /D UNICODE / Gm- /EHsc /RTC1 /MDd /GS /fp:precise /permissive- /Zc:wchar_t /Zc:forScope /Zc:inline /std:c++latest /Fo"x64\Debug\\" /Fd"x64\ Debug\vc142.pdb" /Gd /TP /FC /errorReport:prompt Game.cpp
    • 项目怎么样 - 有点难,因为我已经有成千上万行代码。我可以尝试创建新项目并重新创建此案例
    猜你喜欢
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    • 2022-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多