【发布时间】:2013-08-25 14:15:38
【问题描述】:
我需要一种机制,如果给定类型 T1 和 T2 会生成第三种类型 T3,如果对 (T1, T2) 有效,否则会生成特殊的 Null 类型。
我目前将T1 定义为一个类,在其中我可以将T2 的有效选项集映射到适当的T3。
我正在寻找一种语法,以便可以在T1 的定义中内联定义一组有效的T2。这是解决问题的一种方法,使用重载解析:
#include <utility>
struct X {};
struct Y {};
struct A {};
struct B {};
struct C {};
struct S // T1
{
X member(A) { return X(); } // T2=A, T3=X
Y member(B) { return Y(); } // T2=B, T3=Y
};
struct Null
{
};
template<typename T, typename Arg>
decltype(std::declval<T>().member(std::declval<Arg>()))
call_member(T& t, Arg arg)
{
return t.member(arg);
}
template<typename T>
Null call_member(T& t,...)
{
return Null();
}
int main()
{
S s;
X x = call_member(s, A()); // calls S::member(A)
Y y = call_member(s, B()); // calls S::member(B)
Null null = call_member(s, C());
}
挑战在于处理未找到T2 的情况 - 在上面的示例中由call_member 处理。我试图避免定义Null S::member(...)。
这个例子使用decltype,但是在C++03中有没有办法做到这一点?我对任何替代实现持开放态度(最好对 C++03 友好。)
也可以使用显式特化来实现这种机制,但我正在寻找一种保留与示例中相同的句法结构的方法,以便它可以用以下方式表示:
#define MEMBER(T2, T3) /* implementation details */
struct S : Base // base-class may contain helper code
{
MEMBER(A, X)
MEMBER(B, Y)
};
【问题讨论】:
-
创建有效对
的映射(或多映射),如果对存在则在映射中查找,如果存在则创建T3(T1,T2),保持简单 -
@computer 这可能不是很明显,但我正在寻找一个编译时解决方案——因此是元编程标签。
-
你检查过
boost::mpl::map吗? -
@willj 如果您已经将 boost 作为依赖项存在,那么我认为将这些基本实用程序视为语言原语是一种解放。
-
您可以使用朋友功能代替会员。我们可以使用我的数字将类型与整数和大小以及数组相关联,以从函数调用而不是 decltype 中提取它们。
标签: c++ templates metaprogramming