传递一个数组(变量)作为模板参数

Zha*_*ang 10 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
    }
Run Code Online (Sandbox Code Playgroud)

我想传递一个数组作为模板参数,但失败了.

错误C2672:'__ ExplicitVarTypeTest :: fun':找不到匹配的重载函数

错误C2971:'__ ExplicitVarTypeTest :: fun':模板参数'i5':'i5':具有非静态存储持续时间的变量不能用作非类型参数

有人给我一个解决方案,将varible作为一个有趣的参数传递而不是模板的参数.但在我的情况下,我无法改变函数的论点.因为它是一个回调函数.

实际上,我需要这样做

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);
Run Code Online (Sandbox Code Playgroud)

Bri*_*ian 18

声明模板具有类型的模板参数int[5]实际上会使其具有类型的模板参数int*.这类似于函数签名中发生的衰减.要解决此问题,只需声明fun通过引用获取其数组模板参数:

template<const INT5& i5> void fun();
Run Code Online (Sandbox Code Playgroud)

您希望将数组{2,3,1,2,4}作为模板参数传递给fun.这是可行的,但它必须遵守[expr.const]/5(C++ 17)中对glvalue常量表达式的限制; 它必须引用具有静态存储持续时间的对象.因此,你应该做i5静态:

static constexpr int i5[5] = { 2,3,1,2,4 };
fun<i5>();  // this should work
Run Code Online (Sandbox Code Playgroud)