考虑以下代码
template<typename T, int N>
struct A {
typedef T value_type; // save T to value_type
static const int size = N; // save N to size
};
看,我可以使用value_type
和size
作为模板参数。
typedef A<int, 2> A1;
typedef A<A1::value_type, A1::size + 3> A2; // OK, A2 is A<int,5>
现在我想用指向成员的指针做同样的事情:
struct Foo {
int m;
int r;
};
template<int Foo::*Mem>
struct B {
static int Foo::* const mp;
};
template<int Foo::*Mem>
int Foo::* const B<Mem>::mp = Mem; // Save pointer to member
但我得到错误。
typedef B<&Foo::m> B1;
typedef B<B1::mp> B2; // DOES NOT WORK
如何让最后一行工作? 或者如何获得模拟结果?
注意。我知道它不起作用。不需要指向C ++标准的链接。 我需要解决方法。
答案 0 :(得分:1)
它不应该按照C ++标准5.19 / 2运行:
其他表达式仅被视为常量表达式,仅用于非本地静态对象初始化(3.6.2)。这些常数表达式应评估为以下之一:
- 空指针值(4.10),
- 空成员指针值(4.11),
- 算术常量表达式,
- 地址常量表达式,
- 参考常量表达式,
- 完整对象类型的地址常量表达式,加上或减去整数常量表达式,
或
- 指向成员常量表达式的指针。
这不是原始问题的答案,但它是this错误陈述的答案。
答案 1 :(得分:0)
答案 2 :(得分:0)
不是完全答案,但直接访问Mem工作吗?
ie:B1 :: Mem而不是B1 :: mp。
我很确定标准不允许它,因为我们通常在它是类型而不是直接访问它时键入模板名称,但从技术上讲它可能允许它(不确定是什么意思)。你的解决方案可能肯定无法工作,因为它需要初始化在运行时完成的静态成员(如果我错了就纠正我),所以在编译时无法像你想要的那样访问它。
也许您可以尝试让我们更全面地了解您要对特质/政策类进行的操作,看看是否有合适的解决方法。
答案 3 :(得分:0)
我很惊讶地发现没有这样的东西。至少在预期的地方,例如:
这里没有任何内容http://www.boost.org/doc/libs/1_60_0/libs/type_traits/doc/html/index.html 也不在附近http://en.cppreference.com/w/cpp/types/is_member_pointer
根据此http://www.boost.org/doc/libs/1_60_0/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html和此http://en.cppreference.com/w/cpp/types/is_member_pointer,您不难自行推出。
#include<type_traits> // std::is_pointer_member
template<class MP> struct member_pointer_traits_helper;
template< class T, class U >
struct member_pointer_traits_helper<T U::*>{
using class_type = U;
using declaration_type = T;
};
template< class MP >
struct member_pointer_traits :
member_pointer_traits_helper<typename std::remove_cv<MP>::type> {};
struct B{
int b;
};
int main(){
using std::same;
static_assert(std::is_member_pointer<int B::*>::value == true, "");
static_assert(is_same<member_pointer_traits<int B::*>::class_type, B>{}, "");
static_assert(is_same<member_pointer_traits<int B::*>::declaration_type, int>{}, "");
static_assert(is_same<member_pointer_traits<decltype(&B::b)>::declaration_type, int>{}, "");
// static_assert(is_same<member_pointer_traits<double>::class_type, B>{}, ""); // error
}
我不确定名称是否最佳。
同样,当应用于非成员指针时,这将给出编译器错误(此设计从http://www.boost.org/doc/libs/1_60_0/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html复制),另一种替代方法可能是返回void
类型(这显然是失败返回因为{{1 }}不能是类或成员类型。)
(通过一些小的修改,它可以与C ++ 98一起使用,使用C ++ 11使其更清晰。)