实例化期间未定义的 C++ 内联事件

C++ inlined events undefined during instantiation

提问人:Deus 提问时间:8/20/2023 更新时间:8/20/2023 访问量:58

问:

如果可能的话,我想创建内联事件函数。将 func 指针存储在容器中不是一种方法,因为它们不能内联。事件中的代码将始终被调用,我不想将其添加到一个全局事件函数中。

我的代码:

enum class eGameEvent
{
    LOOP,
    LOAD
};

template<size_t n>
class GameEvent
{
public:
    const static eGameEvent s_event;
    inline static void Event() { }
};

#define GameEvent(t_event)                                                     \
template<> const eGameEvent GameEvent<__COUNTER__>::s_event = t_event;         \
template<> void GameEvent<__COUNTER__>::Event()                                \

class c{};                                                              
std::unique_ptr<c> ptr;

GameEvent(eGameEvent::LOOP)                                                       
{
    //VS: identifier "ptr" is undefined detected during instantiation of class at line
    //but compiles and works as i want
    if(ptr)
    {
         std::cout <<"test\n";
    }
}   

template <std::size_t... Is>
constexpr auto OddIndicesHelper(std::index_sequence<Is...>) 
{
    return std::index_sequence<(2 * Is + 1)...>{};
}

template <std::size_t N>
using OddIndices = decltype(OddIndicesHelper(std::make_index_sequence<N / 2>{}));

template<eGameEvent Event>
constexpr void DeclareEvents()
{
    [] <std::size_t... I>
    (std::index_sequence<I...>)
    {
        (((GameEvent<I - 1>::s_event == Event) ? GameEvent<I>::Event() : [] {}()), ...);

    }(OddIndices<__COUNTER__>{});
}
    
void Loop()
{
    DeclareEvents<eGameEvent::LOOP>();
};

int main()
{
    ptr = std::make_unique<c>();
    
    while(1) Loop();
}

该代码使用 v143 MSVC 进行编译,但是如果我尝试在事件中使用全局变量,我会收到 VS IDE 警告:“标识符”ptr“在 X 行实例化类期间检测到未定义”

它似乎有效,但此代码是否合法并定义了行为? 使用 gcc 使用编译器资源管理器,它也可以毫无问题地编译。

C++ 模板 事件 内联 回调

评论

0赞 HolyBlackCat 8/20/2023
这是一件奇怪的事情。它迫使你把所有的处理程序放在一个翻译单元中,在这一点上,你不能做一个大的吗?switch
0赞 HolyBlackCat 8/20/2023
在我看来是合法的,MSVC 智能感知是有问题的。您可以尝试使用不同的 IDE,使用 Clangd 进行代码完成(VSC 可以使用 Clangd),我从未遇到过这些问题。
0赞 user17732522 8/20/2023
"func 指针存储在容器中不是一种方法,因为它们不能内联。如果容器是例如 a ,那么我相信编译器仍然能够内联。示例:godbolt.org/z/a7PdjG5W9constexpr std::array
0赞 Öö Tiib 8/20/2023
也许 IDE 会被与类模板同名的代码生成宏弄糊涂。如果一个工具被一段代码弄糊涂了,那么大多数人类读者(包括几周后的作者)也会感到困惑。
0赞 Swift - Friday Pie 8/20/2023
@ÖöTiib也可能在 clang\gcc 中中断。从技术上讲,这并不完全合法。

答: 暂无答案