带静态存储的变量地址模板

时间:2014-09-20 06:48:51

标签: c++ templates static

C ++是否允许模板将静态存储的变量地址作为参数?由于内存地址是完整的,并且具有静态存储的地址在编译时是已知的,所以似乎是可能的。

我发现这个问题表明这适用于int *。

Is it legal C++ to pass the address of a static const int with no definition to a template?

到目前为止,我还没有说服我的编译器接受指向char *等其他类型的指针。

模板一般可以专门用于静态地址吗?如果没有,为什么?

编辑:我本来应该更明确。这是一些使用g ++ 4.9编译的代码。

#include <iostream>

template<int* int_addr>
struct temp_on_int{
    temp_on_int() {}
    void print() {
        std::cout << *int_addr << std::endl;
    }
};


template<char* str_addr>
struct temp_on_string{
    temp_on_string() {}
    void print() {
        std::cout << str_addr << std::endl;
    }
};

static int i = 0;
static char j = 'h';
// static char* k = "hi";

int main() {

    temp_on_int<&i> five;
    i = 6;
    five.print();

    temp_on_string<&j> h;
    h.print();

    // temp_on_string<k> hi;
    // hi.print();
}

注释掉是用g ++ 4.9编译的东西。显示的代码不会在coliru上编译。

http://coliru.stacked-crooked.com/a/883df3d2b66f9d61

我如何编译:

g ++ -std = c ++ 11 -Og -g -march = native -Wall -Wextra -pedantic -ftrapv -fbounds-check -o test16 test16.cpp

我尝试编译注释部分时得到的错误:

  

test16.cpp:33:17:错误:'k'的值在常量中不可用   表达式temp_on_string hi;                    ^ test16.cpp:22:14:注意:'k'未被声明为'constexpr'静态字符* k =“hi”;                 ^ test16.cpp:33:18:错误:'k'不是有效的模板参数,因为'k'是变量,而不是变量的地址
  temp_on_string hi;

3 个答案:

答案 0 :(得分:4)

14.3.2
模板非类型参数[temp.arg.nontype]
1
非类型,非模板模板参数的模板参数应为以下之一:[...]    
       
  • 表示完整地址的常量表达式(5.19)    具有静态存储持续时间和外部或内部链接的对象或具有外部或外部的函数    内部联系
[...]

由于k不是常量表达式,因此不能将其用作模板参数。

如果您将k的声明替换为

static char k[] = "hi";

clang++编译它。 g++没有;这是IMO g++中的一个错误。

如果k被声明为

namespace { char k[] = "hi"; }

然后g++也编译它。

答案 1 :(得分:1)

是的,但只有带链接的静态地址才会初始化指针模板参数。您的char *可能无法使用字符串文字,因为它们没有链接。

改为使用名为extern的变量。

答案 2 :(得分:0)

我从未见过,但我不这么认为...... 我试图编译它,但它不起作用,我不能真正看到使用,但这并不意味着它是不可能的......

据我所知,静态变量需要定义,所以它们可以是init,但是它可以被使用(至少大多数时候都是这样)......以及带有模板的静态函数没有问题...只是静态变量,除非你找到一种方法来初始化模板静态变量,而不知道模板类型,而不是它可能会...