簡體   English   中英

是否可以在模板類中編寫一個靜態可變參數模板函數,該函數可以接受N個類型為T的參數?

[英]Is it possible to write a static variadic template function, in a template class, that's able to take N parameters of type T?

我在編寫可變參數函數時遇到了麻煩:

1)采取適當數量的FooArray<T, N>和適當類型的參數N-1 (N always > 2)

2)讓我以自己需要的方式與他們一起玩。

因此,給定以下模板類:

template <typename T, unsigned int N>
class FooArray{
private:
    T m_data[N];
};

以及以下靜態可變參數模板函數聲明:

template <typename T, unsigned int N>
class FooArray{
public:
    template <typename ... ArgT>
    static FooArray<T, N> Weirdness(FooArray<T, N> _arg1, ArgT ... _args);
private:
    T m_data[N];
};

以及該類中的相關實現:

template <typename T, unsigned int N>
template <typename ... ArgT>
FooArray<T, N>
FooArray<T, N>::Weirdness(T _arg1, ArgT ... _args)
{
    static_assert(N > 2, "Not enough Ns for Weirdness.");
    static_assert(N - 2 == sizeof... (_args), "Incorrect parameter number.");

    FooArray<T, N> result;
    // ...
    // Put parameters into table of size N * (N-1) maybe?
    // Do stuff with that to determine result.
    // ...
    return result;
}

我想要給定的代碼(或類似的代碼)在標記的地方返回錯誤,並且在標記的地方也有效。

int main()
{
    FooArray<int, 2> test2parameter;
    FooArray<int, 3> test3param1, test3param2;
    FooArray<int, 4> test4p1, test4p2, test4p3;

    //FooArray<int, 2>::Weirdness(test2parameter); // Should error(and does), not enough N's.

    //FooArray<int, 3>::Weirdness(); // Should error(and does), requires 2 parameters.
    //FooArray<int, 3>::Weirdness(test2parameter); // Should error(and does), requires 2 parameters of type FooArray<int, 3>.
    FooArray<int, 3>::Weirdness(test3param1, test2parameter); // Should error(currently doesn't), all parameters should be FooArray<int, 3>.
    FooArray<int, 3>::Weirdness(test3param1, test3param2); // Valid.

    //FooArray<int, 4>::Weirdness(); // Should error (and does), requires 3 parameters.
    //FooArray<int, 4>::Weirdness(test4p1, test4p2); // Should error (and currently does), requires 3 parameters.
    FooArray<int, 4>::Weirdness(test4p1, test4p2, test3param1); // Should error (currently doesn't), all parameters should be FooArray<int, 4>.
    FooArray<int, 4>::Weirdness(test4p1, test4p2, test4p3); // Valid.

    //FooArray<int, 12>::Weirdness(test12p1, test12p2, test12p3, test12p4, test12p5, test12p6, test12p7, test12p8, test12p9, test12p10, test12p11); // Will be a valid case.

    return 0;
}

回復:第一個問題,我在那里90%。 一旦我讓編譯器因向函數傳遞錯誤的參數類型而向我拋出錯誤,就可以回答問題。

感謝您的時間。 (嚴重的是,如果您時間有限或正試圖解決自己的問題,請立即停止閱讀)

回復:你為什么要這樣做? 我試圖編寫一個N維向量(幾何)叉積函數,因為我認為數學家認為3D向量是唯一可以具有叉積的對象是愚蠢的。 我敢肯定,如果我可以編寫此函數,就可以做到。 另外,我是一個獨立游戲開發商,該功能在我腦子里玩的一些游戲中對我來說很有用。

獎勵材料:使用可變參數模板會給我帶來另一個問題。 一旦將所有這些FooArrays放入Weirdness()函數中,我就必須進行計算,要求(對於返回變量中的每個成員)訪問每個傳遞參數的兩個不同成員。 那么也許這是一個糟糕的設計選擇? 我正在考慮使用遞歸私有靜態可變參數模板函數來填充大小為N *(N-1)的T的靜態數組。 現有功能不允許我使用這種小提琴。 但是,該設計位完全是開放式的,也許需要在一個更加開放式的友好平台上提出另一個問題。 :)

再添加一個靜態斷言:

static_assert(are_same<FooArray<T, N>, ArgT...>::value, "Types do not all match");

並實現are_same<>

template <typename A1, typename A2, typename ... Rest>
struct are_same
{
  enum { value = std::is_same<A1, A2>::value && are_same<A2, Rest...>::value };
};

template <typename A1, typename A2>
struct are_same<A1, A2>
{
  enum { value = std::is_same<A1, A2>::value };
};

我希望使用更簡單的函數聲明,並使用John Zwinck的方法來確保參數類型都是正確的。

template <typename T, unsigned int N>
template <typename ... ArgT>
FooArray<T, N>
FooArray<T, N>::Weirdness(ArgT ... _args)
{
    static_assert(are_same<FooArray<T, N>, ArgT...>::value, "Types do not all match");
    static_assert(N > 2, "Not enough Ns for Weirdness.");
    static_assert(N - 1 == sizeof... (_args), "Incorrect parameter number.");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM