1

我尝试了以下代码。

template <int VAL>
void printVAL()
{
    for(int i=0;i<VAL; i++){
        cout << " i value is "<<i<<endl;
    }
}

实例化:printVAL<100>()

当我使用(std::string s)作为非类型模板参数时,编译器向我大喊以下错误

"class std::basic_str<char>' is not a valid type for a template non-type parameter.

我所知道的是我们应该只使用恒定的整数值。连双倍都没有。

问题:

1) 为什么我们不应该使用 std::string,有什么困扰?

2)“可以使用指向具有外部链接的对象的指针”是什么意思。我可以得到它的任何示例代码吗?

4

4 回答 4

0

您只能将整数值作为非类型模板参数传递。这是语言的限制。您可能需要以下内容:

template<class T>
void printVAL(const T& t)
{
    for (auto& x : t) {
        cout << " x value is "<< x << '\n';
    }
}

这将打印任何内容:容器、字符串、数组等。

于 2013-04-25T12:18:19.730 回答
0

有两种类型的模板:泛型模板和指定类型的模板。

像这样的泛型类型的模板

template<typename T>

或者

template<class T>

这些模板几乎可以用于任何类型。这些类型的实际使用可能会限制可以使用的实际类型。

具有指定类型的模板就像您在问题中遇到的那样:

template<int VAL>

它们只能与匹配指定类型的模板参数一起使用。在这种情况下,只能使用整数文字。

于 2013-04-25T12:15:24.317 回答
0

1) 为什么我们不应该使用 std::string,有什么困扰?

编译器必须能够在编译时推断和替换模板参数。这不能用一个std::string对象来完成,它可以(并且通常会)在运行时改变。

另请参阅此问答

2)“可以使用指向具有外部链接的对象的指针”是什么意思。我可以得到它的任何示例代码吗?

那是因为具有静态存储持续时间的对象的地址(声明的对象extern是)是一个常量表达式。

n3337 5.19/3,强调我的:

文字常量表达式是文字类型的纯右值核心常量表达式,但不是指针类型。整型常量表达式是整型或无范围枚举类型的字面常量表达式。[注意:这样的表达式可以用作数组边界(8.3.4,5.3.4),位域长度(9.6),如果基础类型不固定(7.2),作为枚举器初始化器,作为空指针常量(4.10) 和对齐 (7.6.2)。—尾注] T 类型的已转换常量表达式是字面常量表达式,隐式转换为 T 类型,其中在字面常量表达式中允许隐式转换(如果有),并且隐式转换序列仅包含用户定义的转换,左值到右值转换 (4.1)、整数提升 (4.5) 和整数转换 (4. 7) 除了缩小转换 (8.5.4)。[ 注意:这样的表达式可以用作 case 表达式 (6.4.2),如果底层类型是固定的 (7.2),则可以用作枚举器初始化器,也可以用作整数或枚举非类型模板参数 (14.3)。—尾注] 引用常量表达式是一个左值核心常量表达式,它指定具有静态存储持续时间的对象或函数。地址常量表达式是指针类型的纯右值核心常量表达式,其计算结果为具有静态存储持续时间的对象的地址、函数的地址、空指针值或 std 类型的纯右值核心常量表达式: :nullptr_t。字面常量表达式、引用常量表达式和地址常量表达式统称为常量表达式。

您要求的示例:

#include <iostream>
#include <string>

extern std::string str; // not really neccesary

std::string str;

template<std::string* ptr>
struct S {
    S() { std::cout << ptr->length() << '\n'; }
    ~S() { std::cout << *ptr; }
};

int main()
{
    S<&str> s;
    str = "Hello world!";
}
于 2013-04-25T12:39:15.177 回答
0

根据 14.1/4,

非类型模板参数应具有以下类型之一(可选 cv 限定):

  • 整数或枚举类型,
  • 指向对象的指针或指向函数的指针,
  • 对对象的左值引用或对函数的左值引用,
  • 指向成员的指针,
  • std::nullptr_t.

std::string的不是这些。

于 2013-04-25T12:25:23.593 回答