【问题标题】:Is there a scope shared between instances of a template class?模板类的实例之间是否有共享范围?
【发布时间】:2013-01-12 08:13:16
【问题描述】:

当然,除了全局范围。


我有一个带有宏的自定义断言类来缓存对__FILE__ 的引用:

#define DEFINE_THIS_FILE \
  static const char THIS_FILE__[] = __FILE__

对于源代码,使用宏没什么大不了的,因为每个源都有自己的范围。但是,模板类不能使用源代码,所以我不得不在 TemplateClass.h 给出的声明/定义中进行所有的 ASSERT() 调用

如果我在类定义之外使用宏,例如Singleton

DEFINE_THIS_FILE;

namespace NE
{
  template<typename T>
  class Singleton
  {
    ...
  }
}

然后,宏在#includes Singleton 的任何代码的相同范围内结束,并且编译器为THIS_FILE__ 引发重新定义错误。 (当然,这只有在其他代码使用DEFINE_THIS_FILE宏时才会发生。)

如果我将宏放入声明中,编译器不会抱怨,但链接器将无法为模板类的任何给定实例找到 THIS_FILE__,例如Singleton:

namespace NE
{
  template<typename T>
  class Singleton
  {
    constexpr DEFINE_THIS_FILE;     // constexpr modifier required in this case
    ...
  }
}

我假设我得到的链接器错误,
Undefined symbols for architecture x86_64:
"NE::Singleton<NE::NonTemplateType>::THIS_FILE__"

是由与首次定义 THIS_FILE__ 的范围不同的模板实例引起的,Singleton.h


OT:有没有办法让我的模板类型 Singleton 的所有实例共享一个范围(全局是不可接受的),以便所有实例都可以使用这个静态 const 宏?


编辑1
进一步的测试证实:在包含 ASSERT() 的每个模板化方法中使用宏 DEFINE_THIS_FILE 将正确编译和运行....
在这种情况下,实例不共享范围,但为每个方法定义了 static const char THIS_FILE__。这可行,但我怀疑它使用的 ROM 与 std::assert 一样多或更多(其隐含分配 __FILE__)。

我会解决这个问题,直到对 OT 的回答出现:)


编辑2
傻我。除了使用上面编辑中列出的解决方法,我还不如创建另一个宏 UNCACHED_ASSERT(argsToCheck) 直接使用 __FILE__ 而不是 const 静态表示。
不过,每个方法的多个 ASSERTions 仍然可以从缓存中受益。

不过,仍然需要对 OT 的回答。

【问题讨论】:

  • OT:我真的很好奇。是否有某些原因您不只是将__FILE__ 用于您使用THIS_FILE__ 的任何邪恶目的?毕竟,它是由标准定义的,用于命名您在其中使用它的任何源文件。
  • 正如您自己所说,以这种方式使用时,它将反映包含的 cpp 文件的名称。它是否适用于您期望的标题?
  • 任何有价值的编译器都会为每个文件发出一个字符串的副本。我知道我的。检查你的做法,不要相信那些在更古老的文章中找到智慧的古老文章(1993 年,这甚至不好笑)。
  • 两种方法: 1. 用-S标志编译,看汇编输出; 2.strings yourfile.o | fgrep yourfile.C.
  • 您是否尝试将宏放在未命名的命名空间中? #define DEFINE_THIS_FILE namespace { static const char THIS_FILE__[] = __FILE__; }

标签: c++ templates macros scope


【解决方案1】:

您可以将您的声明放在未命名的命名空间中

#define DEFINE_THIS_FILE namespace { static const char THIS_FILE__[] = __FILE__; }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 2019-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多