gpt4 book ai didi

c++ - 模板类与非模板类,不同编译器的行为

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:53:45 25 4
gpt4 key购买 nike

我在一些应用程序中使用了编译时计数器,它真的很有用。昨天我想用 gcc 编译一个程序(我以前用的是 msvc),计数器的行为在模板类中发生了变化(它在模板类中不再起作用)。

过度简化的代码:

// Maximum value the counter can hold
#define MAX_COUNT 64

// Used to store a number as the size of the structure
template<unsigned int n> struct Count { bool data[n]; };

// Used to overload functions while automatically selecting the
// right one based on the counter value (see following code)
template<int n> struct cn : public cn<n-1> {};
template<> struct cn<0> {};

struct Test
{
#define COUNT \
((sizeof(f(cn<MAX_COUNT + 1>())) / sizeof(bool)) - 1)

static Count<1> f(cn<1>);

/*
f(cn<65>()) will 'call' f(cn<1>) and return a Count<1> with size 1
-> count = 0;
*/
static const int a = COUNT;
static Count<COUNT + 2> f(cn<COUNT + 2>); // increase counter

/*
now Count<2> f(cn<2>) is defined, so:
f(cn<65>()) will 'call' f(cn<2>) and return a Count<2> with size 2
-> count = 1;
*/
static const int b = COUNT;
};

想法是使用函数重载,如果你测试上面的代码它will work perfectly ( a == 0b == 1 )。

但是,如果结构 Test被制作成模板(例如通过在它的声明之前添加template<something>,不需要使用模板参数),the counter breaks最后我得到了 a == b == 1 .这也意味着在这些情况下不可能增加计数器。

所以这是我的问题:

  • 什么模板规则在这里起作用?
  • 为什么会出现这种特定行为?
  • 您是否有让计数器真正工作的解决方法?

注意:我想要一个与旧编译器兼容的 C++03 答案(即使我很想知道针对 C++11 的特定情况的规则是否发生了变化)

编辑:一些输出:

  • VC2010:

    Templated
    a = 0
    b = 1
  • GCC 4.8.1 :

    Templated
    a = 1
    b = 1
  • Clang 3.4 (感谢 dyp):

    Templated
    a = 0
    b = 1

编辑 2

GCC 似乎需要 Count作为从属名称,如 observable here (感谢 dyp)。我在 gcc bugzilla here 中发布了错误报告.

最佳答案

这可能是 C++ 中两阶段名称查找的属性。这是 C++03 的特性,在 C++11 中也存在。 LLVM 项目做了一个 article在此功能上,并将其 Clang 编译器与 GCC 和 Visual C++ 进行比较。 GCC 和 Visual C++ 不支持此功能,但 Visual C++ 确实有一种处理名称查找的方法,允许依赖于两阶段查找的代码比 GCC 更频繁地工作。根据文章,它还允许不是有效 C++ 代码的代码正常工作。

编辑:我误读了这篇文章,GCC 确实实现了两阶段查找,但它可以选择将查找延迟到模板实例化。不过,这确实是 GCC 中的一个错误。

关于c++ - 模板类与非模板类,不同编译器的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23525701/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com