【问题标题】:Constants defined in template classes [duplicate]模板类中定义的常量[重复]
【发布时间】:2012-07-02 09:34:01
【问题描述】:

可能重复:
GCC problem : using a member of a base class that depends on a template argument

我以为我对 C++ 很熟悉,但显然还不够熟悉。
问题是当您在模板类中定义常量时,您可以在派生自该类的新类中使用该常量,但不能在派生自该类的新 template 类中使用该常量。

例如,gcc 说

test.h:18: 错误:'theconstant' 未在此范围内声明

当我尝试编译这个(简化的)头文件时:

#pragma once

template <typename T> class base
{
  public:
    static const int theconstant = 42;
};

class derive1 : public base<size_t>
{
  public:
    derive1(int arg = theconstant) {}
};

template<typename T> class derive2 : public base<T>
{
  public:
    derive2(int arg = theconstant) {} // this is line 18
};

所以问题是一个类 derive1 编译得很好,但另一个类 derive2 是一个模板特化,却没有。
现在可能 gcc 的错误还不够清楚,但我不明白为什么 derive2 中的构造函数与 derive1 中的构造函数具有不同的范围。
万一这很重要,这发生在头文件本身的编译期间,而不是在实例化 derive2&lt;type&gt; 类型的对象时。

我也知道要进行哪些更改才能编译,所以我并不是真的在寻找单行代码作为答案。我想了解为什么会发生这种情况!我尝试搜索网络,但显然我没有使用正确的搜索参数。

【问题讨论】:

  • FWIW,同样的代码在 VC++ 2010 中编译得很好。这可能是 GCC 中的一个错误......
  • derive2(int arg = base&lt;T&gt;::theconstant) {} 编译正常。
  • @dsharlet - 不是 GCC 的错误,如规范中所述。
  • @BoPersson 感谢您指出另一个问题。但是我还是不完全明白。如果编译器只是默默地获取原始标识符,会出现什么问题?您(或任何人)能否举个例子说明哪里会出错?
  • @jrok 我知道!但我想了解的是为什么这在derived2中被认为是必要的,而不是在derived1中,即使继承不是模棱两可的。

标签: c++ templates g++ template-classes


【解决方案1】:

我很确定这会帮助您理解:

您的代码无法编译:

template<typename T> class derive2 : public base<T>
{
  public:
    derive2(int arg = theconstant) {} // this is line 18
};

以及原因:

template <> class base<size_t>
{
  public:
    static const int ha_idonthave_theconstant = 42;
};
derive2<size_t> impossible_isnt_it; 

专业!!!第 18 行的编译器无法确定您不会专门化 base 以使该常量根本不存在。

【讨论】:

  • 这很有意义,我想知道为什么我没有想到...我确实尝试过使用专门的模板,只包含具有不同值的相同成员,但我不能让它不起作用。那好吧。谢谢!
【解决方案2】:

试试

template<typename T> class derive2 : public base<T>
{
  public:
    derive2(int arg = base<T>::theconstant) {} // this is line 18
};

基本上你已经为“theconstant”指定了不完整的范围。

【讨论】:

  • 是的,在 cmets 中提到过。但我想了解的是为什么在derived2 中而不是在derived1 中认为这是必要的,即使继承不是模棱两可的。范围在什么方面不完整?
  • 我猜这与“惰性”模板实例化有关。编译器解析派生2 中的“常量”时没有“基”类。一旦你使用了 base,你就强制编译器“熟悉” base
  • 我得考虑一下。
猜你喜欢
  • 2011-06-27
  • 1970-01-01
  • 2019-10-07
  • 2016-03-05
  • 1970-01-01
  • 1970-01-01
  • 2020-09-11
  • 2016-10-06
  • 2023-03-13
相关资源
最近更新 更多