减少 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;
}

现在,负担是模板用户定义一个标签,然后专门化该标签所需的特征。但是,方法定义只有一个模板参数,在添加或删除更多“参数”(特征)时不需要更改。当然你还需要修复实现。

如果您只是在寻找一些语法糖,我不知道在不更改模板本身的情况下会有什么帮助。