是否可以跨多个源文件构建constexpr数据结构?

问题描述 投票:2回答:1

我正在尝试构建一个用于放置标签的侵入式分析器。如果这些标记可以转换为在编译时直接索引到数据结构中的整数,那将是非常好的,因此配置文件标记的运行时代码尽可能小(例如,可能将整数标识符附加到环形缓冲区)。

是否可以在编译时使用constexpr完成此操作?不用说,标签将出现在几个不同的编译单元中。

我发现在c ++ 17中使用extern的地址是constexpr友好的,但我没有想到一种方法可以让我做到我想要的。

有没有办法做我想要的,或者根本不可能?我看到的主要障碍是,它似乎需要一些编译时状态才能在编译单元之间传输。使用extern技巧,你可以做到这一点,但我不确定被共享的状态对我想做的事情有用。

这是我正在谈论的一个例子:

file1.cpp:

#include <ProfilerThing.h>

#define xstr(a) str(a)
#define str(a) $a

int function1()
{
    static constexpr auto token1 = MakeGlobalToken(__PRETTY_FUNCTION__ " at " __FILE__ ": " xstr(__LINE__));
    BeginProfile(token1);

    EndProfile(token1);
}

file2.cpp:

int function2()
{
    static constexpr auto token2 = MakeGlobalToken(__PRETTY_FUNCTION__ " at " __FILE__ ": " xstr(__LINE__));
    BeginProfile(token2);

    EndProfile(token2);
}

MakeGlobalToken会是什么样子?甚至可以写? token1token2必须是独一无二的。理想情况下,它们将成为某种数据结构的索引。

c++ c++17 constexpr
1个回答
2
投票

首先想到的是地址。它们保证是独一无二的,易于清洗。

template<auto>
struct token
{
    inline static struct {} dummy;
};

template<auto x>
constexpr void* MakeGlobalToken()
{
    return &token<x>::dummy;
}

用作

inline std::unordered_map<void*, int> logger;

void BeginProfile(void* token)
{
    logger[token]++;
}

void EndProfile(void* token)
{
    logger[token]++;
}

int function1()
{
    static constexpr auto token1 = MakeGlobalToken<function1>();
    BeginProfile(token1);

    EndProfile(token1);
}

int function2()
{
    static constexpr auto token2 = MakeGlobalToken<function2>();
    BeginProfile(token2);

    EndProfile(token2);
}
© www.soinside.com 2019 - 2024. All rights reserved.