Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass an array (variable) as template argument

Tags:

c++

typedef int INT5[5] ;
    template<INT5 i5>
    void fun()
    {
        for (auto i : i5)
        {
            cout << i << endl;
        }
    }

    void test()
    {
        int i5[5] = { 2,3,1,2,4 };
        fun<i5>();//error
    }

I want to pass an array as a template argument, but failed.

error C2672: '__ExplicitVarTypeTest::fun': no matching overloaded function found

error C2971: '__ExplicitVarTypeTest::fun': template parameter 'i5': 'i5': a variable with non-static storage duration cannot be used as a non-type argument

Someone give me a solution to pass the varible as a fun's argument rather than the template's argument. But in my situation, I can't change the function's argument. because it's a callback function.

Actually, I need to do this

typedef char MyCharMap[UINT8_MAX];
    template<MyCharMap keymap>
    LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
        //MSDN说了,nCode<0(HC_ACTION)的都用CallNextHookEx返回
        if (nCode >= HC_ACTION)
        {
            KBDLLHOOKSTRUCT* pStruct = (KBDLLHOOKSTRUCT*)lParam;
            if (keyMap[pStruct->vkCode])
            {
                switch (wParam)
                {
                case WM_KEYDOWN:
                    keybd_event(keyMap[pStruct->vkCode], 0, 0, 0);
                    break;
                case WM_KEYUP:
                    keybd_event(keyMap[pStruct->vkCode], 0, KEYEVENTF_KEYUP, 0);
                    break;
                default:
                    throw "other key event";
                }
            }
            return TRUE;
        }
        //传给系统中的下一个钩子   
        return CallNextHookEx(keyHook, nCode, wParam, lParam);
    }

SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc<keymap1>, theApp.m_hInstance, NULL);
SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc<keymap2>, theApp.m_hInstance, NULL);
like image 819
Zhang Avatar asked Jun 08 '18 06:06

Zhang


People also ask

Can you pass an array as an argument?

Arrays can be passed as arguments to method parameters. Because arrays are reference types, the method can change the value of the elements.

Can we pass array as argument in C?

Just like normal variables, Arrays can also be passed to a function as an argument, but in C/C++ whenever we pass an array as a function argument then it is always treated as a pointer by a function.

Can you pass an array as an argument C++?

C++ does not allow to pass an entire array as an argument to a function. However, You can pass a pointer to an array by specifying the array's name without an index.

Can we pass Nontype parameters to templates?

Template classes and functions can make use of another kind of template parameter known as a non-type parameter. 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.


1 Answers

Declaring a template to have a template parameter of type int[5] actually causes it to have a template parameter of type int*. This is similar to the decay that occurs in function signatures. To fix this, simply declare fun to take its array template argument by reference instead:

template<const INT5& i5> void fun();

You want to pass the array {2, 3, 1, 2, 4} as the template argument to fun. That's doable, but it has to obey the restrictions on glvalue constant expressions in [expr.const]/5 (C++17); it must refer to an object with static storage duration. Therefore, you should make i5 static:

static constexpr int i5[5] = { 2,3,1,2,4 };
fun<i5>();  // this should work
like image 192
Brian Bi Avatar answered Oct 13 '22 00:10

Brian Bi