【问题标题】:Template on address of variable with static storage带有静态存储的变量地址模板
【发布时间】:2014-09-20 06:48:50
【问题描述】:

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 嗨; ^ test16.cpp:22:14: 注意:'k' 没有被声明为 'constexpr' static char* k = "hi"; ^ test16.cpp:33:18: 错误:“k”不是有效的模板参数,因为“k”是一个变量,而不是变量的地址
temp_on_string hi;

【问题讨论】:

  • 你是说你的编译器接受了那个代码,但是如果你把int改成char,然后什么都不改,你的编译器会拒绝它吗?
  • 问题不清楚 - 已编辑。

标签: c++ templates static


【解决方案1】:
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++ 也会编译它。

【讨论】:

  • 哇,不错的发现!我希望我能 +2。
【解决方案2】:

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

改用命名的extern 变量。

【讨论】:

  • 您能再解释一下吗?没有链接是什么意思?这与静态链接不同吗?这些关于指针模板参数的规则是在标准中明确规定的,还是由于其他原因而产生的?
  • @Praxeolitic “无链接”是由于字符串文字没有名称。该规则被 n.m. 引用
【解决方案3】:

我从来没有见过,但是,我不这么认为...... 我试图编译它,但它不起作用,我看不到它的用途,但这并不意味着它是不可能的......

据我所知,静态变量需要定义,所以它们可以用一些东西初始化,所以它可以被使用(至少大多数时候都是这样做的)......而且对于带有模板的静态函数,没有问题...只是静态变量,除非您找到一种在不知道模板类型的情况下初始化模板静态变量的方法,否则可能会这样做...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-05
    • 2019-05-10
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多