是否在模板类的实例之间共享了作用域?

时间:2013-01-12 08:13:16

标签: c++ templates macros scope

当然,除了全球范围之外。


我有一个带有宏的自定义断言类,用于缓存对__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宏?


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

我会满足于此,直到OT的答案出现:)


EDIT2
傻我。我不如使用上面编辑中列出的变通方法,而是创建另一个宏,UNCACHED_ASSERT(argsToCheck)直接使用__FILE__而不是const静态表示。
但是,每种方法的多个ASSERT仍然可以从缓存中受益。

但仍然需要OT的答案。

1 个答案:

答案 0 :(得分:1)

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

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