C / C ++宏扩展为参数,参数为字符串

时间:2011-12-21 23:13:25

标签: c++ c-preprocessor stringification

我有许多变量的名称与工程规范文档中的元素相同,因此名称的字符串版本也很有用。

我发现自己经常使用像这样的宏:

#define MACRO(a) a, #a

典型用法是:

void someFunction(int a, const char *name);

someFunction(MACRO(meaningfully_named_variable));

我的问题有三个:

  • 有更好的方法吗?
  • Boost或其他库中是否有类似的宏?
  • 如果没有,我如何改进并重命名,以使其清晰有用?

修改 我应该说上面是一个很小的例子。该函数可能具有其他参数,并且命名实体可能是数据成员,甚至可能是函数本身。

我正在为C ++考虑的另一个扩展是一个可以接收宏内容的类NamedRef

template <typename T>
struct NamedRef
{
    NamedRef(T *t, const char *name) : t(t), name(name) { }
    T *t;
    const char *name;
};

template <typename T>
NamedRef<T> namedRef(T &t, const char *name)
{
    return NamedRef<T>(&t, name);
}

#define WITH_NAME(a) a, #a

// more sophisticated usage example
void otherFunction(double, NamedRef<int>, bool);

otherFunction(0.0, namedRef(object.WITH_NAME(meaningful_member_name)), false);

4 个答案:

答案 0 :(得分:5)

你可以更进一步:

#define SOMEFUNCTION(a) somefunction(a, #a)

但是,这仅在您调用相同的功能时才有用。否则,我认为没有比你的例子更好的方法了。当然,您应该将宏的名称更改为更有意义的内容,例如ARGUMENTS或其他内容。

答案 1 :(得分:0)

#define someFunction(a)  if (1) stringized_someFunction((a), #a ); else (void)0
void stringized_someFunction(int a, const char* name);

if(1)stuff包装了宏,因此它不会(通常)与循环,分支,if语句等混乱。

然后你会像这样调用你的函数:

int r = 4;
someFunction(r);

你只为每个“功能声明”添加一个额外的行。如果C预处理器允许多个步骤,你可以把它全部包装成一个,但是唉,它没有。

我忘了,因为我希望很明显你需要写下你的功能:

void stringized_someFunction(int a, const char* name)
{
  // Do stuff here
}

无论如何,以这种方式阅读应该会更容易和更漂亮。

答案 2 :(得分:0)

您可能会发现XMACRO对此类工作很有用。

答案 3 :(得分:0)

耶西回答说,

你可以这样写:

void function1(int a, const char* name)
{
    cout << "a: " << a << endl;
    cout << "name: " << name << endl;
}

void function2(double d, const char* name, const char *str)
{
    cout << "d: " << d << endl;
    cout << "name: " << name << endl;
    cout << "str: " << str << endl;
}

#define MACRO(functionName, a) functionName(a, #a)
#define MACRO2(functionName, a, ...) functionName(a, #a, __VA_ARGS__)

int main()
{
    int a = 10;
    MACRO(function1, a);
    double d = 10.5;
    MACRO2(function2, d, "Hello world");
    return 0;
}

如果要传递更多参数,可以使用使用变量参数的MACRO2。您必须相应地传递函数名称。