【问题标题】:Trouble with templates and __LINE__模板和 __LINE__ 的问题
【发布时间】:2010-11-08 23:35:19
【问题描述】:

我正在编写一些我想集成到库中的代码。我希望它没有外部依赖并且符合标准。我想使用模板来创建唯一类型以允许编译时类型检查。

更新:
下面的代码来自 msdn,这不是我尝试做的。我尝试做的是每次用户使用宏实例化它时使用模板来拥有唯一的类型。这种方式可以在编译时检查类型是否混合。我正在处理本文中的代码:http://www.artima.com/cppsource/safelabels.html,是的,我知道 std::bitset 的存在,谢谢。

正如 Tony 指出的那样,__LINE__ 无论如何都不是唯一性的有力保证。

我遇到以下错误:

http://msdn.microsoft.com/en-us/library/kyf0z2ka%28v=VS.100%29.aspx

C2975 will also occur when you use `__LINE__` as a compile-time constant with /ZI:

// C2975b.cpp
// compile with: /ZI
// processor: x86
template<long line> 
void test(void) {}

int main() {
    test<__LINE__>();   // C2975
    test<__LINE__>();   // OK
}

不使用 /ZI 编译一切都很好,但它是 msvc 中的默认设置,我不希望我的库的所有用户首先遇到编译器错误,直到我告诉他们打开那个开关。

你会如何解决这个问题?

到目前为止,我唯一现实的想法是检查 msvc 的存在,然后为 msvc 使用 __COUNTER__...

更新:
实际上__COUNTER__ 不起作用,因为我需要每个声明的类型都是唯一的,但对于不同的翻译单元,它们必须相同,否则我会遇到未解析的外部引用的链接器问题。

【问题讨论】:

  • erm... 这不是我见过的模板template&lt;class T&gt; void test(void) {} 将是我知道的标准方式
  • 如果您只想要一个唯一的值,那么在 MSVC 上使用 __COUNTER__ 并在其他所有内容上使用 __LINE__ 怎么样? __COUNTER__ 会触发同样的警告吗?
  • 我认为 Boost 可能在某个地方隐藏了一些功能来生成这样的独特类型。可能值得一看。
  • @ufotds:对不起,没有意识到你已经尝试过了,并且有点困惑你是否只是想要唯一的价值。听起来好像__LINE__(不一致)不是/ZI 的编译时常量。我肯定会通过使用解决方法来解决它,而不是告诉我的客户使用符合要求的编译器^W^W^W /Zi
  • 这将如何处理使用不同文件中同一行的模板的人?如果您仍然得到一个损坏的解决方案,那么找出如何解决这个奇怪的 VC++ 怪癖似乎没有多大意义......

标签: c++ visual-c++ templates types standards


【解决方案1】:

获得唯一实例化的第一个挑战是区分翻译单元。幸运的是,这一点很简单:

namespace { struct unique_type {}; }
template<typename T> int foo() { return 42; }
static int bar = foo<unique_type>();

这可以放在标题中,并在每个翻译单元中实例化不同的foo&lt;unique_type&gt;()。由于 MSVC 错误,添加 __LINE__ 需要一些工作:

namespace {
    struct unique_type{};
    const int LINE = __LINE__;
}
template<typename T, int N> int foo() { return 42; }
static int bar = foo<unique_type, LINE>();

【讨论】:

  • 嗨,谢谢。匿名命名空间技巧非常酷。我很高兴了解到这一点。但是我不完全明白发生了什么。你似乎创造了一个独特的功能? bar 的类型总是 int 对吗?我尝试做的是编译时检查,所以事实上据我所知,它是一种在一个翻译单元中是唯一的类型。我想防止用户使用运算符和分配基本上是 int 的东西,但具有不同的语义含义,不应该混合使用。所以我想传递一些独特的东西作为模板的参数,这样我就得到了一个独特的类型。
  • 事实证明__LINE__ 可能不是最好的,因为如果人们在同一行的不同标题或同一行的同一文件中声明某些内容,那不是唯一的。我目前有一个宏,它对最终用户隐藏所有这些。他们只需指定其类型的名称,然后就可以放心,它不会与其他地方声明的其他类型混在一起。
  • 仅使用 __COUNTER__ 可以工作,但不符合标准且并非所有编译器都支持
  • @ufotds:是的,条形图只是一个虚拟定义,所以我可以展示foo&lt;unique_type&gt; 的实例化。每个翻译单元(.cpp 加上它的标头)都有自己的匿名命名空间,因此有自己的unique_type,因此也有自己的foo&lt;unique_type&gt;
猜你喜欢
  • 2013-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-14
  • 1970-01-01
相关资源
最近更新 更多