Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pointer as non-type template argument

Tags:

When answering this SO question, I found in the Standard (already C++03, still in C++11) that you can only use addresses as non-type template arguments if they're of the form & id-expression (plus some exceptions).

But I couldn't answer why this is the case.

14.3.2 Template non-type arguments [temp.arg.nontype]

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 an object with static storage > duration and external or internal linkage or a function with external or internal linkage, including function templates and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as & id-expression, except that the & may be omitted if the name refers to a function or array and shall be omitted if the corresponding template-parameter is a reference; [...]

(n3485, emphasis mine)

Example:

using TFoobar = int (*)(); template < TFoobar tp > struct foo_struct{};  int foobar() { return 42; } constexpr TFoobar pFoobar = &foobar;  foo_struct < &foobar > o0; // fine foo_struct < pFoobar > o1; // ill-formed 

I guess it has something to do with the translation phases, namely the compiler doesn't know much about addresses. Yet, why isn't it allowed? Shouldn't it be possible for the compiler to use something similar to macro substitution to replace pFoobar with &foobar?

like image 994
dyp Avatar asked Apr 08 '13 17:04

dyp


People also ask

Can we use non-type parameters as arguments template?

Non-type template arguments are normally used to initialize a class or to specify the sizes of class members. For non-type integral arguments, the instance argument matches the corresponding template parameter as long as the instance argument has a value and sign appropriate to the parameter type.

What are non-type parameter for templates?

A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument. A non-type parameter can be any of the following types: An integral type. An enumeration type.

What are template arguments?

In C++ this can be achieved using template parameters. A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

Can template have default parameters?

Template parameters may have default arguments. The set of default template arguments accumulates over all declarations of a given template.


1 Answers

Consider classes Foo<&X> and Foo<&Y>, both with a static member int Bar. The linker must be able to tell whether your program has 1 or 2 Bar objects. Now consider that the linker is also the party most likely responsible for assigning values to &X and &Y.

Look at the Standard again. As it's written, the compiler doesn't need to communicate the actual address to the linker. Instead, it passes the id-expression. Linkers are already quite capable of determining whether two id-expression's are the same, even before assigning a numerical address to them.

like image 188
MSalters Avatar answered Jan 21 '23 10:01

MSalters