【问题标题】:C Preprocessing Token concatenationC 预处理令牌连接
【发布时间】:2016-03-02 02:30:09
【问题描述】:

如何使用 C 预处理自动生成以下代码模式(访问器)?

// Immutable accessor.
const auto& member1 () const {
  return _member1;  // private class member
}

// Mutable accessor.
auto& member1() {  
  return _member1;  // private class member
}

我尝试了以下方法,但没有成功...

#define EXPAND_ACCESSOR(item) constexpr const auto& ##item() const { return _##item; } \
                              constexpr auto& ##item() { return _##item; }


EXPAND_ACCESSOR(member1)  // didn't work

【问题讨论】:

  • 您需要在每一行的末尾使用 \(后面没有空格)。
  • 我做到了。编译器抱怨错误:粘贴“&”和“member1”没有给出有效的预处理标记#define EXPAND_ACCESSOR(item) constexpr const auto& ##item() const { return _##item; }\
  • #define 不适用于空格,除非在字符串内部,这就是使用 DEFINE _CONSTNAT 等的原因。使用 typedef 将最后一个单词替换为之前的所有内容,包括多行。以 ; 结尾

标签: c c-preprocessor


【解决方案1】:

您可以使用宏来完成您正在尝试的事情。您的宏需要一些调整。 (我用三行来帮忙解答)

你有:

#define EXPAND_ACCESSOR(item) \
   constexpr const auto& ##item() const { return _##item; } \
   constexpr auto& ##item() { return _##item; }

宏的问题:

   constexpr const auto& ##item() const { return _##item; } \
                         ^^ Not appropriate.

我从 g++ 收到以下错误:

error: pasting "&" and "member1" does not give a valid preprocessing token

你只需要使用:

#define EXPAND_ACCESSOR(item) \
   constexpr const auto& item() const { return _##item; } \
   constexpr auto& item() { return _##item; }

这修复了处理器错误,但会导致与返回类型相关的错误。如果返回类型中有 auto,则需要使用尾随返回类型。

constexpr 与非const 成员函数一起使用是不合适的。当成员函数用constexpr 限定时,它被假定为const 成员函数。因此,您需要从该函数中删除 constexpr

这是一个应该可以工作的固定宏:

#define EXPAND_ACCESSOR(item) \
   constexpr const decltype( _ ## item) & item() const { return _ ## item; } \
   decltype( _ ## item) & item() { return _ ## item; }

【讨论】:

  • 嗨,萨胡,谢谢。这正是我想要的。请您再次帮助我处理我打算生成的 EXPAND_MUTATOR(item) set_item(const decltype(item)& val) { _item = val; } ?我试过 #define EXPAND_MUTATOR(item) void set_item(const decltype(_##item)& val) { _##item = val; } 但它无法编译。
  • @Jes,你需要使用set_ ## item来创建set_member1。宏需要定义为#define EXPAND_MUTATOR(item) void set_##item(const decltype(_##item)& val) { _##item = val; }
【解决方案2】:

typedef 语法:

typedef struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
 } Book;

'Book' 被替换为之前的整个结构定义。 ;在 {} 内有效。

【讨论】:

  • 这个答案和这个问题有什么关系?
猜你喜欢
  • 2022-12-11
  • 1970-01-01
  • 2011-04-22
  • 2012-03-28
  • 2015-09-13
  • 2020-11-14
  • 1970-01-01
  • 2013-11-10
  • 2014-07-30
相关资源
最近更新 更多