[英]C++ SFINAE double nested initializer_list vs. variadic template constructor
我正在編寫一個包含Vector
和Matrix
類的小型數學庫。 我想通過嚴格的初始化規則來方便地初始化這些類的對象。
Vector
class 構造函數已經按我的預期工作。 它受到限制,只接受正確的大小N
,除此之外,所有 arguments 都是同一類型(見下文)。
Vector
template <std::size_t N, typename T>
class Vector{
public:
template <typename... TArgs,
std::enable_if_t<
sizeof...(TArgs) == N &&
(std::is_same_v<T, std::remove_reference_t<TArgs>> && ...),int> = 0>
Vector(TArgs &&... args) : data_{std::forward<TArgs>(args)...} {}
// ...
private:
std::array<T,N> data;
}
示例初始化(有效,受限制)
Vector<3,int> v{1,2,3}
Matrix
template <std::size_t N, std::size_t M, typename T>
class Matrix{
public:
/* put restriction rules here */
Matrix(std::initializer_list<std::initializer_list<T>> lst) {
int i = 0;
int j = 0;
for (const auto &l : lst) {
for (const auto &v : l) {
data[i][j] = v;
++j;
}
j = 0;
++i;
}
}
// ...
private:
std::array<Vector<M, T>, N> data;
}
示例初始化 1(有效,不受限制)
Matrix<2,3,int> m{ {1,2,3}, {4,5,6} }
示例初始化 2(編譯,但不應該!!)
Matrix<2,3,int> m{ {1,'a',3}, {4,5,6,7,8,9} }
我無法使用可變參數模板為雙嵌套初始化實現Matrix
class 構造函數,因此我使用了嵌套的std::initializer_list
(來自這篇文章)。 它可以工作,但我希望對這個構造函數有與Vector
class 相同的限制。
我怎樣才能做到這一點?
關於這里的這篇文章... ::std::initializer_list vs variadic templates我可以說我真的不喜歡使用 initializer_list 或 variadic 模板。 在這種情況下,任何一個看起來都很好,但據我所知,在編譯時獲取std::initializer_list
的大小有點困難。
您可以簡單地使Matrix
采用 2D 數組引用,如下所示:
Matrix(T const (&m)[N][M])
這只會在您指定的條件下編譯,並且調整您的代碼的 rest 也很容易。 您可以應用相同的原理來簡化Vector
。
要獲得所需的語法,您可以這樣做:
template <typename ... Us,
std::enable_if_t<sizeof...(Us) == N && (std::is_same_v<Us, T> && ...), int> = 0>
Matrix(const Us (&... rows)[M]) {
// ...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.