Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 根据参数的数量生成多个宏调用_C++_Macros_Variadic Macros - Fatal编程技术网

C++ 根据参数的数量生成多个宏调用

C++ 根据参数的数量生成多个宏调用,c++,macros,variadic-macros,C++,Macros,Variadic Macros,我尝试以重复的方式多次调用此函数 template<class T> void METADATA_METHODS_IMPL(std::string& metadata, const T &value, const std::string &key) { metadata += boost::format("%1%:%2%") % key % value(); } 等等 我需要调用METADATA\u方法\u IMPL\u N,其中N是中的许多参数 #

我尝试以重复的方式多次调用此函数

template<class T>
void METADATA_METHODS_IMPL(std::string& metadata, const T &value, const std::string &key)
{
    metadata += boost::format("%1%:%2%") % key % value();
}
等等

我需要调用
METADATA\u方法\u IMPL\u N
,其中
N
中的许多参数

#define METADATA_METHODS(...)\
std::string METADATA_METHODS_IMPL_FUNC()\
{\
    std::string metadata;\
    BOOST_PP_OVERLOAD(METADATA_METHODS_IMPL_,__VA_ARGS__)(metadata, __VA_ARGS__)\
    return metadata;\
}
上面的代码(带有
BOOST\u PP\u重载
)给出了不合适的结果:

class X
{
    std::string F1();
    std::string F2();
    std::string F3();

    METADATA_METHODS(F1, F2, F3);
};
这导致

std::string METADATA_METHODS_IMPL_FUNC() 
{
    std::string metadata; 
    METADATA_METHODS_IMPL(metadata, F1, F2, F3, "F1", "F2", "F3"); 
    METADATA_METHODS_IMPL(metadata, , ""); 
    METADATA_METHODS_IMPL(metadata, , ""); 
    return metadata; 
};
我想要这样的东西:

std::string METADATA_METHODS_IMPL_FUNC() 
{
    std::string metadata; 
    METADATA_METHODS_IMPL(metadata, F1, "F1"); 
    METADATA_METHODS_IMPL(metadata, F2, "F2"); 
    METADATA_METHODS_IMPL(metadata, F3, "F3"); 
    return metadata; 
};
  • 有人知道如何达到预期的结果吗
  • 我可以使用
    Boost.preprocessor
    library为[1..10]中的一些
    K
    使用
    METADATA\u方法\u IMPL\u 1

    • 使用这些宏,我们可以使预处理器继续重新扫描并允许递归宏

      #define EVAL(...)  EVAL3(EVAL3(EVAL3(__VA_ARGS__)))
      #define EVAL3(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__)))
      #define EVAL2(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__)))
      #define EVAL1(...) EVAL0(EVAL0(EVAL0(__VA_ARGS__)))
      #define EVAL0(...) __VA_ARGS__
      
      我们可以定义一些辅助函数来建立概念

      #define CAT(a, ...) PRIMITIVE_CAT(a,__VA_ARGS__)
      #define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
      
      #define EMPTY()
      #define EAT(...)
      #define IDENT(...) __VA_ARGS__
      #define DEFER(id) id EMPTY()
      #define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)()   
      
      #define I_TRUE(t,f) t
      #define I_FALSE(t,f) f
      #define I_IS_DONE(a,b,...) b
      #define TRUE_DONE() ~, I_TRUE
      #define IS_DONE(b) OBSTRUCT(I_IS_DONE)(CAT(TRUE_,b)(),I_FALSE) 
      
      并构建这个宏映射函数,将第一个参数带到每个宏映射函数

      #define MM() MM_CALL
      #define MM_NEXT(Macro,md,a,...) \
        IS_DONE(a)(                    \
           EAT                          \
        ,                                \
           OBSTRUCT(MM)()                 \
        )                                  \
        (Macro,md,a,__VA_ARGS__)
      #define MM_CALL(Macro,md,a,...)   \
        Macro(md,a)                      \
        MM_NEXT(Macro,md,__VA_ARGS__)
      #define MacroMap(Macro,md,...) EVAL(MM_CALL(Macro,md,__VA_ARGS__,DONE))
      
      在定义了与实现相关的功能之后

      #define METADATA_METHODS_IMPL_MACRO(md,a) \
        METADATA_METHODS_IMPL(md, a, #a);
      
      #define METADATA_METHODS(md,...) \
        MacroMap(METADATA_METHODS_IMPL_MACRO,md,__VA_ARGS__) \
        return md
      
      这:

      结果如下(添加一些格式后):


      这里有一个可能重复的有用的东西:@Plasmah,我想在第二个问题得到回答之前,这个话题是不能结束的。不过,谢谢你的帮助。一个问题,一个问题:)@maverik:这就是为什么把多个问题作为一个问题发布是不好的,所以:我相信很多人也会忽略第二个问题。记住,这样做也会为其他人保留问题;我建议你为你的第二个问题打开一个新的问题,并在那里详细解释。@Plasmah,你是对的。不管怎样,我正在检查你建议的主题的答案。第二个不适合我(在VS2008中)。
      #define METADATA_METHODS_IMPL_MACRO(md,a) \
        METADATA_METHODS_IMPL(md, a, #a);
      
      #define METADATA_METHODS(md,...) \
        MacroMap(METADATA_METHODS_IMPL_MACRO,md,__VA_ARGS__) \
        return md
      
      METADATA_METHODS(metadata, F1, F2, F3);
      
      METADATA_METHODS_IMPL(metadata, F1, "F1");
      METADATA_METHODS_IMPL(metadata, F2, "F2");
      METADATA_METHODS_IMPL(metadata, F3, "F3");
      return metadata;