减少 C++ 中模板参数的重复
Reducing duplication of template parameters in C++
这不是主要的代码破解问题,我只是想知道我是否遗漏了一些巧妙的技巧。
如果我正在写一个模板class,我可能会这样开始:
// some_header.h
template <typename TypeParameter, size_t max_array_size>
class TemplatedClass
{
std::array<TypeParameter, max_array_size> MyTemplatedArray;
public:
TypeParameter do_something()
{
/* do something with TypeParameter and max_array_sizein here */
}
}
这很好,但是当我有不那么琐碎的模板示例时,我倾向于将函数定义与声明分开,如下所示:
// some_header.h
template <typename TypeParameter, size_t max_array_size>
class TemplatedClass
{
std::array<TypeParameter, max_array_size> MyTemplatedArray;
public:
TypeParameter do_something();
/*
Many more function declarations
*/
}
template <typename TypeParameter, size_t max_array_size>
TemplatedClass<TypeParameter, max_array_size>::do_something()
{
/* do something with TypeParameter and max_array_sizein here */
}
/*
Many more function definitions, all with:
template <typename TypeParameter, size_t max_array_size>
TemplatedClass<TypeParameter, max_array_size>
at the start
*/
这样做的目的是要有一个 classic 框架 class 定义,其他人一眼就能轻松阅读。我不介意这样做,但烦人的是当我想修改模板参数时。第一个示例中的一个更改是第二个示例中的 1 + 2 * n
个更改!
所以我想知道的是:有没有办法让第二个例子的模板参数更易于维护?可能类似于 typedef/using 或者我没听说过的关键字?
第一个没有回答:
假设,/*do something*/
取决于模板参数。在那种情况下,必须修复签名是一个较小的问题。您需要修复实现。
另一种情况是/*do something*/
不依赖模板参数。然后你可以将方法移动到非模板基础 class.
更认真的尝试回答问题:
如果 TemplatedClass
只有一个模板参数而不是多个模板参数怎么办?您可以使用单个标记而不是为 TemplatedClass
使用一堆模板参数,并且可以将实际参数的定义推迟到特征:
#include <array>
template <typename Tag> struct value_type_impl;
template <typename Tag> using value_type = typename value_type_impl<Tag>::type;
template <typename Tag> constexpr int array_size = 123;
template <typename Tag>
class TemplatedClass {
std::array<value_type<Tag>, array_size<Tag> > MyTemplatedArray;
public:
value_type<Tag> do_something();
};
template <typename Tag>
value_type<Tag> TemplatedClass<Tag>::do_something() {
return {};
}
// the tag
struct foo_tag{};
// specializations for foo_tag:
template <> struct value_type_impl<foo_tag> { using type = int; };
template <> constexpr int array_size<foo_tag> = 123;
int main() {
TemplatedClass<foo_tag> tc;
}
现在,负担是模板用户定义一个标签,然后专门化该标签所需的特征。但是,方法定义只有一个模板参数,在添加或删除更多“参数”(特征)时不需要更改。当然你还需要修复实现。
如果您只是在寻找一些语法糖,我不知道在不更改模板本身的情况下会有什么帮助。
这不是主要的代码破解问题,我只是想知道我是否遗漏了一些巧妙的技巧。
如果我正在写一个模板class,我可能会这样开始:
// some_header.h
template <typename TypeParameter, size_t max_array_size>
class TemplatedClass
{
std::array<TypeParameter, max_array_size> MyTemplatedArray;
public:
TypeParameter do_something()
{
/* do something with TypeParameter and max_array_sizein here */
}
}
这很好,但是当我有不那么琐碎的模板示例时,我倾向于将函数定义与声明分开,如下所示:
// some_header.h
template <typename TypeParameter, size_t max_array_size>
class TemplatedClass
{
std::array<TypeParameter, max_array_size> MyTemplatedArray;
public:
TypeParameter do_something();
/*
Many more function declarations
*/
}
template <typename TypeParameter, size_t max_array_size>
TemplatedClass<TypeParameter, max_array_size>::do_something()
{
/* do something with TypeParameter and max_array_sizein here */
}
/*
Many more function definitions, all with:
template <typename TypeParameter, size_t max_array_size>
TemplatedClass<TypeParameter, max_array_size>
at the start
*/
这样做的目的是要有一个 classic 框架 class 定义,其他人一眼就能轻松阅读。我不介意这样做,但烦人的是当我想修改模板参数时。第一个示例中的一个更改是第二个示例中的 1 + 2 * n
个更改!
所以我想知道的是:有没有办法让第二个例子的模板参数更易于维护?可能类似于 typedef/using 或者我没听说过的关键字?
第一个没有回答:
假设,/*do something*/
取决于模板参数。在那种情况下,必须修复签名是一个较小的问题。您需要修复实现。
另一种情况是/*do something*/
不依赖模板参数。然后你可以将方法移动到非模板基础 class.
更认真的尝试回答问题:
如果 TemplatedClass
只有一个模板参数而不是多个模板参数怎么办?您可以使用单个标记而不是为 TemplatedClass
使用一堆模板参数,并且可以将实际参数的定义推迟到特征:
#include <array>
template <typename Tag> struct value_type_impl;
template <typename Tag> using value_type = typename value_type_impl<Tag>::type;
template <typename Tag> constexpr int array_size = 123;
template <typename Tag>
class TemplatedClass {
std::array<value_type<Tag>, array_size<Tag> > MyTemplatedArray;
public:
value_type<Tag> do_something();
};
template <typename Tag>
value_type<Tag> TemplatedClass<Tag>::do_something() {
return {};
}
// the tag
struct foo_tag{};
// specializations for foo_tag:
template <> struct value_type_impl<foo_tag> { using type = int; };
template <> constexpr int array_size<foo_tag> = 123;
int main() {
TemplatedClass<foo_tag> tc;
}
现在,负担是模板用户定义一个标签,然后专门化该标签所需的特征。但是,方法定义只有一个模板参数,在添加或删除更多“参数”(特征)时不需要更改。当然你还需要修复实现。
如果您只是在寻找一些语法糖,我不知道在不更改模板本身的情况下会有什么帮助。