【问题标题】:C++ templates and C preprocessorC++ 模板和 C 预处理器
【发布时间】:2016-06-30 15:05:08
【问题描述】:

考虑一下这段代码。代码做什么并不重要,重要的是如何编写模板样板代码。

从样板的角度来看,该代码有一些重要的优势。

  • 样板代码少得多。

  • 如果您决定采用更多模板参数,则只需更改类定义和#define

缺点很明显:

  • 使用预处理器

  • 不太可读

  • 很奇怪

有没有像这样标准化的东西?


#include <cstdio>

template<typename T>
struct Summator{
    Summator(T v1, T v2);

    T value1();
    T value2();

    T sum();

    bool great();

private:
    T v1;
    T v2;
};


#define Summator_(type) template<typename T> type Summator<T>


Summator_()::Summator(T v1, T v2) : v1(v1), v2(v2){};

Summator_(T)::value1(){
    return v1;
}

Summator_(T)::value2(){
    return v1;
}

Summator_(T)::sum(){
    return v1 + v2;
}

Summator_(bool)::great(){
    return v1 > v2;
}

int main(){
    Summator<int> s{ 5, 6 };

    printf("%d\n", s.sum() );
}

【问题讨论】:

  • 最接近的可能是std::accumulate()
  • @πάνταῥεῖ 我认为他指的是使用Summator_ 来缩写模板定义shiver
  • 这是关于不必在每个类外成员函数定义前写出template&lt;class T&gt; /*return_type*/ Summator&lt;T&gt;::?最近有一些关于标准提案的讨论,但绝对不会制作 C++17。
  • 使用这样的预处理器通常是导致维护问题的主要原因。忘记一些可能导致奇怪错误的东西也很容易,比如你自己忘记了Summator_()::Summator(...)中的T
  • P0223

标签: c++ templates c-preprocessor dry


【解决方案1】:

鉴于大多数实际用途,类模板的成员函数必须是内联的,您不妨在调用主体中定义它们。特别是对于像这样的微小功能。

显然,真正的类模板可能具有一两个重要的功能 - 但您只需要这些一两个功能的样板。

标准中没有任何定义可以帮助解决这个问题,我不确定我是否希望有。如果您必须这样做,请记住在之后 #undef 定义(因为否则您将污染您的类用户的 #define 命名空间)。

【讨论】:

    【解决方案2】:

    如果我正确理解您的问题,您是否希望避免在每个函数定义前编写整个模板?

    我认为大多数关心这一点的人都依赖 IDE 来生成空函数定义/重构现有函数?

    我不认为使用宏是一个好主意,只是为了节省一点打字,感觉就像一场维护噩梦。

    【讨论】:

      【解决方案3】:

      样板代码少得多。

      不,是一样的

      如果您决定采用更多模板参数,则只需更改类定义和#define。

      阅读:如果你决定彻底改变设计......也许你可以节省一些打字(但话又说回来,也许不会)

      使用预处理器

      是的 - 所以那是不正确的。

      不那么可读

      所以又说“不”

      很奇怪

      无关

      有没有像这样标准化的东西?

      显然不是

      【讨论】:

        猜你喜欢
        • 2011-04-26
        • 2010-11-11
        • 1970-01-01
        • 2015-11-21
        • 1970-01-01
        • 2014-02-26
        • 2012-06-25
        • 2010-09-07
        • 1970-01-01
        相关资源
        最近更新 更多