我想调用一个带有一些参数的宏,这取决于boost::mpl::eval_if
(或类似函数)的结果,它可以给出多少模板参数不为空。假设我们有一些伪代码,如下所示:
struct EmptyType { };
template<class arg1=EmptyType, class arg2=EmptyType, class arg3=EmptyType>
class my_class
{
eval_if<is_not_same<arg1, EmptyType>, FILL_MY_CLASS_DEFINE(1)> else
eval_if<is_not_same<arg2, EmptyType>, FILL_MY_CLASS_DEFINE(2)> else
eval_if<is_not_same<arg3, EmptyType>, FILL_MY_CLASS_DEFINE(3)>;
};
我试图用一些内容填充我的课程,具体取决于EmptyType
的参数数量。我想知道如何通过Boost.MPL / Preprocessor或其他一些Boost库在C ++ 03中完成这样的事情?
答案 0 :(得分:2)
您不需要预处理器或mpl。您需要部分专业化:
编辑这适用于C ++ 03,现场直播:https://ideone.com/6MaHJ
#include <iostream>
#include <string>
struct EmptyType { };
template<class arg1=EmptyType, class arg2=EmptyType, class arg3=EmptyType>
class my_class
{
// FILL_MY_CLASS_DEFINE(3)
};
template<class arg1, class arg2>
class my_class<arg1,arg2,EmptyType>
{
// FILL_MY_CLASS_DEFINE(2)
};
template<class arg1>
class my_class<arg1,EmptyType,EmptyType>
{
// FILL_MY_CLASS_DEFINE(1)
};
template<>
class my_class<EmptyType,EmptyType,EmptyType>
{
// FILL_MY_CLASS_DEFINE(0)
};
int main(int argc, const char *argv[])
{
my_class<std::string, double, int> a;
my_class<std::string, int> b;
my_class<void> c;
return 0;
}
答案 1 :(得分:1)
您在寻找可变参数模板吗?
#include <tuple>
#include <iostream>
#include <string>
template <typename... Arg>
struct my_class
{
// getting the size of the argument list:
enum { size = sizeof...(Arg) }; // in absense of static fields with initializers...
// demo filling the struct with data:
std::tuple<Arg...> arg_data;
my_class(Arg&&... a) : arg_data(std::forward<Arg>(a)...) { }
};
int main(int argc, const char *argv[])
{
my_class<std::string, int> a("hello world", 42);
std::cout << "size: " << a.size << std::endl;
std::cout << "last: " << std::get<a.size-1>(a.arg_data) << std::endl;
return 0;
}
输出:
size: 2
last: 42
答案 2 :(得分:0)
如果您有许多模板参数,则部分特化可能不切实际且容易出错。 下面的代码可以满足您的需求,但正如其他答案中已经提到的那样,并不总是最好的方法。
#include <boost/mpl/count_if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/type_traits/is_same.hpp>
using boost::is_same;
using boost::mpl::_;
using boost::mpl::not_;
using boost::mpl::count_if;
#define FILL_MY_CLASS_DEFINE(x) static const int __x__ = x // an example, watch out: no semicolon at the end
struct EmptyType { };
template<class arg1=EmptyType, class arg2=EmptyType, class arg3=EmptyType>
class my_class
{
// count the types which are not equal to EmptyType
static const long NonEmptyCount = count_if<type, not_<is_same<_, EmptyType> > >::value;
// invoke a macro with an argument
FILL_MY_CLASS_DEFINE(NonEmptyCount);
};