基础类模板参数的有意义名称

Meaningful names for base class template arguments

本文关键字:有意义 参数 基础类      更新时间:2023-10-16

中的命名基类非类型参数的最佳方法是什么
class Derived : public Base<Argument> {
...
}

如果我能做到这一点,那将是很棒的:

class Derived : public Base<Argument> {
  constexpr static int Argument = 1;
...
}

,但在派生的课程声明期间尚未定义参数。

我可以使用#define,但是我也想将此名称嵌入一个名称空间。

可以解释以下讨论,即标准做法是

template<int N>
class Base {
protected:
  static const int n = N;
  ...
};

并在需要此值的任何地方使用" n"作为有意义的名称。

使用派生类中基类的模板参数

但是,该值本身在派生类声明中看起来已加密:

class Derived : public Base<whatever value>

此方法是最佳选择吗?

编辑:我的动机是为其他开发人员提供促进对此论点的修改。他们更容易修改

中的" buffersize = 1024"行
class MyScreen : public ScreenBase<BufferSize> {
    ... BufferSize = 1024;

而不是

class MyScreen : public ScreenBase<1024> {

这是用虚构名称的很难推理,但是,如果我正确理解您,您想拥有模板参数的名称(例如,快速搜索它们(。

我认为这不是一个大问题,您总是可以搜索每次Base<T>用作基类(即使是public Base<的普通幼稚的grep也可以。而且您不能删除模板以支持A 属性或ctor参数,然后您只需要为您的值引入一个命名的容器:

#include <type_traits>
#include <cstddef>
template<std::size_t V>
struct buffer_size : public std::integral_constant<std::size_t, V> {};

现在您的课程声明将是:

template<typename S>
struct buffered_stream<S> {
   static constexpr std::size_t size = S::value;
};

现在,当您使用它时,您可以清楚地了解该参数是什么:

struct network_stream : public buffered_stream<buffer_size<1024>> {
   // ...
};

请注意,这是受模板实例化方法的启发,例如,您可以在std::chrono::duration中看到。出于同样的原因,您还应考虑使用用户定义的后缀(当它们足够清晰时(。例如,这在许多情况下可能就足够了:

struct network_stream : public buffered_stream<1024_bytes> {
   // ...
};

请将此代码视为起点,当然,您想使用std::is_same()来产生一些不错的编译器诊断(尤其是如果您有一个以上命名参数(。仅此一项就可以使您的代码比此概念证明更加复杂,但我想您现在了解如何做。