【问题标题】:Typedef templated functionTypedef 模板化函数
【发布时间】:2017-06-28 08:25:55
【问题描述】:

鉴于我有一个由枚举模板化的函数,我想“typedef/alias”该函数以简化其使用。类似的问题在这里:(Typedef with template functions, C++11: How to alias a function?)

以下是我想出的三种可能的解决方案,以及我不喜欢它们的地方:

  1. 编写一个封装函数的宏。问题:宏(命名空间安全?)
  2. 静态函数指针。问题:变量(例如,需要添加 #pragma 部分以禁用 Wunused-variable)
  3. 为每种情况明确编写函数。问题:创建全新的函数(即不仅仅是重命名原来的函数),更容易出错,更多的函数调用
  4. 与 3. 相同,但内联保留在标题中。这可能是我最喜欢的。问题:创建全新的函数(即不仅仅是重命名原来的函数),更多的函数调用

上面列出的方法是否还有其他特别的优点/缺点(除了个人不喜欢)?是否应该不惜一切代价避免一些?

虚拟示例:

foo_lib.h

#ifndef _FOO_LIB_H_
#define _FOO_LIB_H_

enum class Score {
    LOSS = 0,
    DRAW = 1,
    WIN = 3
};

void AddScore(int *current_score_p, const Score &score);

template <Score SCORE>
void AddScore(int *current_score_p) {
    AddScore(current_score_p, SCORE);
}

// 1. macro
#define ADD_SCORE_DRAW(current_score_p) AddScore<Score::DRAW>((current_score_p))

// 2. static function pointer (auto would work too)
static void (*AddScoreDrawStatic)(int *current_score_p) = &AddScore<Score::DRAW>;

// 3. Explicit function for each case
void AddScoreDrawSpecial(int *current_score_p);

// 4. Like 3., but inline to keep in header
inline void AddScoreDrawInline(int *current_score_p) { AddScore<Score::DRAW>(current_score_p); }

#endif // _FOO_LIB_H_

foo_lib.cpp

#include "foo_lib.h"

void AddScore(int *current_score_p, const Score &score) {
    *current_score_p += static_cast<int>(score);
}

void AddScoreDrawSpecial(int *current_score_p) {
    AddScore<Score::DRAW>(current_score_p);
}

【问题讨论】:

    标签: c++ templates alias typedef


    【解决方案1】:

    如果您的目的是将分数添加到整数并将结果存储在整数中,最简单的做法是创建一个可以像 score = add_score(score, Score::DRAW); 那样调用的函数,其可读性非常好。另外,我讨厌宏。

    int add_score(int previous_score, Score score);
    

    在我看来,使用非类型模板参数进行模板化并不能提高可读性

    【讨论】:

    • 谢谢。没错,这也是我的初始函数正在做的事情(写入指针与返回值除外)。这里的这个分数示例只是一个代码 sn-p 虽然我需要它的实际应用程序要复杂一些。
    • @Cedric 您能否详细说明您的实际用例如何比您在问题中提出的更复杂?这可能会影响我的回答
    • 我有一个包含不同模块的框架,由 ModuleID(枚举)标识。然后我有转换函数,需要数据来自哪里以及去哪里,例如AddData(module_id 源,module_id 本地,数据)。我想为每个模块都有一个版本,所以我可以例如在模块“home”中的任何地方都说 AddDataHome(module_id source, data),而不必每次都传递它自己的 id。
    • @Cedric 那么为什么我上面解释的那种功能不能在你的情况下工作呢?
    • 它会工作,但我必须在每次函数调用时传递模块自己的 ID,这似乎没有必要。
    猜你喜欢
    • 1970-01-01
    • 2019-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多