Template on address of variable with static storage

有些话、适合烂在心里 提交于 2020-01-13 19:30:11

问题


Does C++ allow templates to take the address of a variable with static storage as a parameter? Since a memory address is integral and those with static storage are known at compile time it seems possible.

I found this question showing that this works for int*.

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

So far, I haven't convinced my compiler accept pointers to other types like char*.

Can templates be specialized on static addresses in general? If not, why?

Edit: I should have been more explicit. Here is some code that compiles for me using 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();
}

Commented out is something that won't compile with g++ 4.9. The code as shown won't compile on coliru.

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

How I compiled:

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

The error I get when I try to compile the commented portion:

test16.cpp:33:17: error: the value of 'k' is not usable in a constant expression temp_on_string hi; ^ test16.cpp:22:14: note: 'k' was not declared 'constexpr' static char* k = "hi"; ^ test16.cpp:33:18: error: 'k' is not a valid template argument because 'k' is a variable, not the address of a variable
temp_on_string hi;


回答1:


14.3.2
  Template non-type arguments [temp.arg.nontype]
    1
      A template-argument for a non-type, non-template template-parameter shall be one of: [...]
  • a constant expression (5.19) that designates the address of a complete object with static storage duration and external or internal linkage or a function with external or internal linkage
     [...]

Since k is not a constant expression, you cannot use it as a template argument.

If you replace the declaration of k with

static char k[] = "hi";

clang++ compiles it. g++ does not; this is IMO a bug in g++.

If k is declared as

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

then g++ compiles it too.




回答2:


Yes, but only static addresses with linkage will initialize a pointer template parameter. Your char * probably didn't work with a string literal, because those have no linkage.

Use a named, extern variable instead.




回答3:


I've never seen that but, i don't think so... i tried to compile it, but it doesn't work, i can't really see the use, but that doesn't mean it is impossible...

To my knowing, static variables need to be define, so they can be init with something, so it can be used (at least that is what most times do)... and well with static functions with template there is no problem... just the static variable, unless you find a way to init a template static variable, with out knowing the template type, than it might be done...



来源:https://stackoverflow.com/questions/25946089/template-on-address-of-variable-with-static-storage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!