4

I would like to use an array pointer (with array arithmetic) as a non-type argument. I understand that the argument should be known at compile-time, but isn't it the case for a fixed size global array?

This example can print the first 2 lines, but not the third one. Is there any workaround for this?

EDIT: I am looking for an answer for not only aa+1, but all aa+is where i is less than the size of aa

#include <iostream>

void print (int n) {
    printf("the value is: %d\n", n);
}

template <int *n>
void myWrapper() {
    print(*n);
}

void myCall(void (*CALLBACK)(void)) {
    CALLBACK();
}

int a = 1; int aa[4] = {2,3,4,5}; 

int main()
{
    myCall(myWrapper<&a>); // prints 1
    myCall(myWrapper<aa>); // prints 2
    /* the following line gives error: no matches converting function 'myWrapper' to type 'void (*)()' 
       note: candidate is: template<int* n> void myWrapper() 
    */
    myCall(myWrapper<aa+1>); 
}
6
  • Why not change template<int *n> void myWrapper() to void myWrapper(int *n)? Commented May 1, 2015 at 10:11
  • uh! sorry. I had to tell. I am using an API, which only accepts void functions. That's a workaround to pass a parameter with a callback. Commented May 1, 2015 at 10:15
  • 1
    Note that the template's arguments have to be known at compile time. So I think templates are not the solution here. Commented May 1, 2015 at 10:26
  • @TOWI_Parallelism In that case, you should pass a lambda like [int *p](){ /*something with p*/}, no? As Axalo writes, I'm afraid you're misusing the template mechanism - in any case, you won't be able to do it with runtime parameters. Commented May 1, 2015 at 10:29
  • The solution we had worked for most of the functions. Passing an address of a variable (which is known at compile time). Then changing the variable itself at runtime causes no problem. But if want to have multiples of these (in an array), then the problem occurs. I haven't used C++11. I don't know if there is a better solution for this Commented May 1, 2015 at 10:32

1 Answer 1

6

This is excluded by a note to [temp.arg.nontype]:

3 - [ Note: Addresses of array elements and names or addresses of non-static class members are not acceptable template-arguments. [...]

A workaround could be to supply the array index as another template parameter:

template <int *n, unsigned N = 0>
void myWrapper() {
    print(n[N]);
}

// ...
myCall(myWrapper<aa, 1>); 
Sign up to request clarification or add additional context in comments.

1 Comment

thanks for your smart answer, but I wanted to try it now. Ami is right. The main purpose of using this was to pass an argument to the function. We still have to pass numbers as array indeces. I was thinking about something that can work with aa[i] or aa+i in general. Although i is always gonna be 0<= i < sizeof(aa)/sizeof(int)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.