模板参数列表的 C++ 别名
C++ Alias for list of template parameters
我有很多 C++ classes 使用相同的模板参数列表
template<typename T, typename Index, typename Bool, typename Data, Index n_x, Index n_u, Index n_c, Index n_w>
class A {
...
};
template<typename T, typename Index, typename Bool, typename Data, Index n_x, Index n_u, Index n_c, Index n_w>
class B {
...
};
template<typename T, typename Index, typename Bool, typename Data, Index n_x, Index n_u, Index n_c, Index n_w>
class C {
...
};
你懂的。然后我将它们实例化为
A<T, Index, Bool, Data, n_x, n_u, n_c, n_w> a;
B<T, Index, Bool, Data, n_x, n_u, n_c, n_w> b;
C<T, Index, Bool, Data, n_x, n_u, n_c, n_w> c;
有没有办法以某种方式为这组模板参数创建一个别名,这样我就不必保留 re-typing 参数列表?
我有这样的想法...
using Params = T, Index, Bool, Data, n_x, n_u, n_c, n_w;
A<Params> a;
B<Params> b;
C<Params> c;
我意识到我可以创建一个单独的 class 来定义类型,然后使用它。但我想知道是否有一种方法可以在不定义新 class 的情况下执行此操作。
编辑
我不想使用宏。
我也不想使用默认值,因为这需要确保默认值在一堆文件中是统一的。我意识到我可以定义一个新的 header 默认值并将其包含在所有文件中,但这似乎是糟糕的编程。
与您的要求不完全相同,但差别不大...
但需要一些工作。
你可以用结构解决,foo
,双层模板管理。
template <typename T, typename Index, typename Bool, typename Data,
Index I1, Index I2, Index I3, Index I4>
struct foo
{
template <template <typename, typename X, typename, typename, X, X, X, X>
class Cont>
using type = Cont<T, Index, Bool, Data, I1, I2, I3, I4>;
};
第一层,结构层,包含您要修复的 types/values(在您的示例中为 T, Index, Bool, Data, n_x, n_u, n_c, n_w
)。
第二层,即 using
层,具有可变模板元素(A
、B
和 C
,在您的示例中。
您还可以添加一个 using
别名 foot_t
以简化使用
template <template <typename, typename X, typename, typename, X, X, X, X>
class Cont, typename C>
using foo_t = typename C::template type<Cont>;
现在您可以使用 using
修复类型和值(第一层)
using f = foo<T, Index, Bool, Data, n_x, n_u, n_c, n_w>;
并使用foo_t
声明激活第二层的变量
foo_t<A, f> a;
foo_t<B, f> b;
foo_t<C, f> c;
以下是一个完整的工作示例
#include <vector>
#include <iostream>
template <typename T, typename Index, typename Bool, typename Data,
Index n_x, Index n_u, Index n_c, Index n_w>
class A { };
template <typename T, typename Index, typename Bool, typename Data,
Index n_x, Index n_u, Index n_c, Index n_w>
class B { };
template <typename T, typename Index, typename Bool, typename Data,
Index n_x, Index n_u, Index n_c, Index n_w>
class C { };
template <typename T, typename Index, typename Bool, typename Data,
Index I1, Index I2, Index I3, Index I4>
struct foo
{
template <template <typename, typename X, typename, typename, X, X, X, X>
class Cont>
using type = Cont<T, Index, Bool, Data, I1, I2, I3, I4>;
};
template <template <typename, typename X, typename, typename, X, X, X, X>
class Cont, typename C>
using foo_t = typename C::template type<Cont>;
int main ()
{
using T = float;
using Index = std::size_t;
using Bool = bool;
using Data = std::vector<std::string>;
constexpr std::size_t n_x { 0U };
constexpr std::size_t n_u { 1U };
constexpr std::size_t n_c { 2U };
constexpr std::size_t n_w { 3U };
using f = foo<T, Index, Bool, Data, n_x, n_u, n_c, n_w>;
foo_t<A, f> a;
foo_t<B, f> b;
foo_t<C, f> c;
static_assert( std::is_same<decltype(a),
A<T, Index, Bool, Data, n_x, n_u, n_c, n_w>>{}, "!" );
static_assert( std::is_same<decltype(b),
B<T, Index, Bool, Data, n_x, n_u, n_c, n_w>>{}, "!" );
static_assert( std::is_same<decltype(c),
C<T, Index, Bool, Data, n_x, n_u, n_c, n_w>>{}, "!" );
}
您可以用一个定义来替换别名,虽然不完美,但很简单,而且很有效。
#define PARAMS T, Index, Bool, Data, n_x, n_u, n_c, n_w
A<PARAMS> a;
B<PARAMS> b;
C<PARAMS> c;
注意:定义末尾没有;
。
我有很多 C++ classes 使用相同的模板参数列表
template<typename T, typename Index, typename Bool, typename Data, Index n_x, Index n_u, Index n_c, Index n_w>
class A {
...
};
template<typename T, typename Index, typename Bool, typename Data, Index n_x, Index n_u, Index n_c, Index n_w>
class B {
...
};
template<typename T, typename Index, typename Bool, typename Data, Index n_x, Index n_u, Index n_c, Index n_w>
class C {
...
};
你懂的。然后我将它们实例化为
A<T, Index, Bool, Data, n_x, n_u, n_c, n_w> a;
B<T, Index, Bool, Data, n_x, n_u, n_c, n_w> b;
C<T, Index, Bool, Data, n_x, n_u, n_c, n_w> c;
有没有办法以某种方式为这组模板参数创建一个别名,这样我就不必保留 re-typing 参数列表?
我有这样的想法...
using Params = T, Index, Bool, Data, n_x, n_u, n_c, n_w;
A<Params> a;
B<Params> b;
C<Params> c;
我意识到我可以创建一个单独的 class 来定义类型,然后使用它。但我想知道是否有一种方法可以在不定义新 class 的情况下执行此操作。
编辑
我不想使用宏。
我也不想使用默认值,因为这需要确保默认值在一堆文件中是统一的。我意识到我可以定义一个新的 header 默认值并将其包含在所有文件中,但这似乎是糟糕的编程。
与您的要求不完全相同,但差别不大...
但需要一些工作。
你可以用结构解决,foo
,双层模板管理。
template <typename T, typename Index, typename Bool, typename Data,
Index I1, Index I2, Index I3, Index I4>
struct foo
{
template <template <typename, typename X, typename, typename, X, X, X, X>
class Cont>
using type = Cont<T, Index, Bool, Data, I1, I2, I3, I4>;
};
第一层,结构层,包含您要修复的 types/values(在您的示例中为 T, Index, Bool, Data, n_x, n_u, n_c, n_w
)。
第二层,即 using
层,具有可变模板元素(A
、B
和 C
,在您的示例中。
您还可以添加一个 using
别名 foot_t
以简化使用
template <template <typename, typename X, typename, typename, X, X, X, X>
class Cont, typename C>
using foo_t = typename C::template type<Cont>;
现在您可以使用 using
using f = foo<T, Index, Bool, Data, n_x, n_u, n_c, n_w>;
并使用foo_t
foo_t<A, f> a;
foo_t<B, f> b;
foo_t<C, f> c;
以下是一个完整的工作示例
#include <vector>
#include <iostream>
template <typename T, typename Index, typename Bool, typename Data,
Index n_x, Index n_u, Index n_c, Index n_w>
class A { };
template <typename T, typename Index, typename Bool, typename Data,
Index n_x, Index n_u, Index n_c, Index n_w>
class B { };
template <typename T, typename Index, typename Bool, typename Data,
Index n_x, Index n_u, Index n_c, Index n_w>
class C { };
template <typename T, typename Index, typename Bool, typename Data,
Index I1, Index I2, Index I3, Index I4>
struct foo
{
template <template <typename, typename X, typename, typename, X, X, X, X>
class Cont>
using type = Cont<T, Index, Bool, Data, I1, I2, I3, I4>;
};
template <template <typename, typename X, typename, typename, X, X, X, X>
class Cont, typename C>
using foo_t = typename C::template type<Cont>;
int main ()
{
using T = float;
using Index = std::size_t;
using Bool = bool;
using Data = std::vector<std::string>;
constexpr std::size_t n_x { 0U };
constexpr std::size_t n_u { 1U };
constexpr std::size_t n_c { 2U };
constexpr std::size_t n_w { 3U };
using f = foo<T, Index, Bool, Data, n_x, n_u, n_c, n_w>;
foo_t<A, f> a;
foo_t<B, f> b;
foo_t<C, f> c;
static_assert( std::is_same<decltype(a),
A<T, Index, Bool, Data, n_x, n_u, n_c, n_w>>{}, "!" );
static_assert( std::is_same<decltype(b),
B<T, Index, Bool, Data, n_x, n_u, n_c, n_w>>{}, "!" );
static_assert( std::is_same<decltype(c),
C<T, Index, Bool, Data, n_x, n_u, n_c, n_w>>{}, "!" );
}
您可以用一个定义来替换别名,虽然不完美,但很简单,而且很有效。
#define PARAMS T, Index, Bool, Data, n_x, n_u, n_c, n_w
A<PARAMS> a;
B<PARAMS> b;
C<PARAMS> c;
注意:定义末尾没有;
。