Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using pointer template parameters

Tags:

c++

templates

I have the following code:

struct Port {
    int reg1;
    int reg2;
};

#define PORT1 ((Port *) 0x00010000); // absolutely compile-time constants
#define PORT2 ((Port *) 0x00020000);

template <Port * port>
class PortWrapper {
public:
    PortWrapper() {
        port->reg1 = 1;
        port->reg2 = 2;
    }
};

constexpr static const Port * const port1c = PORT1;

int main(int argc, char* argv[]) {
    PortWrapper<PORT1> port1; //Compiler says: error: could not convert template argument '65536u' to 'Port*'
    PortWrapper<port1c> port1; //Compiler says: error: 'port1c' is not a valid template argument because 'port1c' is a variable, not the address of a variable 
}

How can I instantiate this template?

I can do this:

Port port;
int main() {
    PortWrapper<&port> port1;
}

But that's not what I need. I need port to be mapped to predefined constant address.

like image 582
cos Avatar asked May 15 '14 10:05

cos


People also ask

Why do we use :: template template parameter?

8. Why we use :: template-template parameter? Explanation: It is used to adapt a policy into binary ones.

Which is correct example of template parameters?

For example, given a specialization Stack<int>, “int” is a template argument. Instantiation: This is when the compiler generates a regular class, method, or function by substituting each of the template's parameters with a concrete type.

Can we pass Nontype parameters to templates?

Template non-type arguments in C++It is also possible to use non-type arguments (basic/derived data types) i.e., in addition to the type argument T, it can also use other arguments such as strings, function names, constant expressions, and built-in data types.

What is a template parameter C++?

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.


1 Answers

You can't as-is, because non-type template arguments of pointer type can only be null pointer expressions or addresses of objects, and a conversion from an integer is neither of those.

You could redesign the template slightly:

template <uintptr_t portAddr>
class PortWrapper {
private:
  static constexpr Port* port() { return (Port*)portAddr; }

public:
  PortWrapper() {
    port()->reg1 = 1;
    port()->reg2 = 2;
  }
};

Note that in the comments, @KonradRudolph disputes whether this strictly follows the rules for a constexpr function, and it's quite possible it does not. Nevertheless, even if constexpr is omitted from the above, any decent compiler will inline the call of port(), effectively resulting in compile-time evaluation.

like image 64
Angew is no longer proud of SO Avatar answered Oct 25 '22 21:10

Angew is no longer proud of SO