【问题标题】:Templates and const on c++c++中的模板和常量
【发布时间】:2012-02-13 11:30:16
【问题描述】:

我有以下模板:

#include <iostream> 
template <class T,T defaultVal, int dim=255> 
class Vec 
{ 
    T _vec[dim]; 
    int _dim; 
public: 
    Vec () : _dim(dim) 
    { 
        for (int i=0;i<_dim;++i) 
        { 
            _vec[i] = defaultVal; 
        } 
    } 
    ~Vec () {}; 
    // other operators and stuff 
}; 
int main () 
{ 
    int defValue = 0; 
    Vec < int,defValue > vecWithDefVal; 
}

但是程序不会编译,因为在编译期间必须知道模板值,即 const 或 const-literal。

我真的不明白这个错误,谁能给我解释一下?

【问题讨论】:

  • 在您最喜欢的 C++ 书籍中查找“常量表达式”。

标签: c++ templates constants


【解决方案1】:

模板类是在编译时创建的,因此必须在编译时知道该值。如果不是const,直到运行时才知道,所以编译器无法创建模板类。

【讨论】:

  • 可以只是一个数字吗?说4? (很抱歉没有自己编译,现在不在我的电脑上)。
  • 是的,这是一个常量表达式(检查链接页面,“literals”)
  • 是的。此外:模板 如果 T 和 int 兼容(或者有一个 T 的构造函数采用 int)也可以工作
【解决方案2】:

正如编译器告诉你的,它必须是一个常量表达式。

使用const int defValue = 0;

【讨论】:

  • 没有 const,defValue 不是常量表达式。现在:msdn.microsoft.com/en-us/library/3ffb821x.aspx 直到有人为您挖掘相关的 c++ 标准段落。
  • @itzik984:与运行时的 C# 泛型不同,模板是编译时间。因此,您需要在编译时对所有内容进行评估。
  • @Aamir:C# 泛型中是否有类似的运行时构造(也就是说,您可以使用未知(在编译时)类型或值作为参数动态创建参数化类型吗?
【解决方案3】:

一般来说,为每个要使用的值使用不同的类型并没有多大用处。在大多数情况下,我希望您希望使用T() 作为默认默认值(不,重复的“默认”不是类型),并有可能使用构造函数参数覆盖对象的默认值。当您想在运行时确定值时,使用默认模板参数不起作用。

事实上,问题中的代码说明了为什么使用默认值作为模板参数是有问题的:您只能使用常量表达式作为参数。也就是说,只有编译器在编译时可以计算出的参数是可行的。此外,这些也需要清楚地标记为常量:

int const defValue = 0;

要处理非整数类型,您可以考虑在命名空间范围内使用指针或对对象的引用。但是,我认为这里真正需要的是使用构造函数参数。

【讨论】:

    【解决方案4】:
    const int defValue = 0;
    Vec<int, defValue> vecWithDefVal;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-17
      • 1970-01-01
      • 1970-01-01
      • 2011-04-26
      • 2017-06-24
      • 1970-01-01
      • 2011-06-17
      相关资源
      最近更新 更多