相关疑难解决方法(0)

C++ 编译时程序范围内的唯一编号

我想出了一个问题的解决方案,但我不确定它是否总是有效或仅适用于我的编译器。首先,问题:我注意到在许多情况下,即使给定相同的类型,也希望每次使用时都重新实例化模板类(假设您的模板类具有初始化为函数调用的静态成员)有一些重要的副作用——并且您希望每次使用模板时都会产生这种副作用)。最简单的方法是给你的模板一个额外的整数参数:

template<class T, class U, int uniqueify>
class foo
{
...
}
Run Code Online (Sandbox Code Playgroud)

但是现在您必须手动确保每次使用 foo 时都会为 uniqueify 传递一个不同的值。天真的解决方案是这样使用__LINE__

#define MY_MACRO_IMPL(line) foo<line>
#define MY_MACRO MY_MACRO_IMPL(__LINE__)
Run Code Online (Sandbox Code Playgroud)

不过这个解决方案有一个问题——__LINE__每个翻译单元都被重置。因此,如果两个翻译单元在同一行上使用模板,则模板只会实例化一次。这似乎不太可能,但想象一下,如果确实发生了编译器错误,那么调试它会有多困难。同样,您可以尝试__DATE__以某种方式用作参数,但它只有几秒钟的精度,而且是编译开始的时间,而不是到达该行的时间,因此如果您使用的是 make 的并行版本,则有两个翻译单元是相当合理的同__DATE__

另一种解决方案是一些编译器有一个特殊的非标准宏,__COUNTER__它从 0 开始,每次使用时递增。但它遇到了同样的问题——每次调用预处理器都会重置它,因此它会重置每个翻译单元。

另一种解决方案是一起使用__FILE____LINE__

#define MY_MACRO_IMPL(file, line) foo<T, U, file, line>
#define MY_MACRO MY_MACRO_IMPL(T, U, __FILE__, __LINE__)
Run Code Online (Sandbox Code Playgroud)

但是您不能根据标准将字符文字作为模板参数传递,因为它们没有外部链接。

即使这确实有效,__FILE__标准中也没有定义是包含文件的绝对路径还是仅包含文件本身的名称,因此如果您在不同的文件夹中有两个相同的命名文件,这仍然可能会中断。所以这是我的解决方案:

#ifndef toast_unique_id_hpp_INCLUDED
#define toast_unique_id_hpp_INCLUDED

namespace {
namespace toast {
namespace detail {

template<int i>
struct translation_unit_unique {
    static int …
Run Code Online (Sandbox Code Playgroud)

c++ templates c-preprocessor

5
推荐指数
1
解决办法
1830
查看次数

标签 统计

c++ ×1

c-preprocessor ×1

templates ×1