【发布时间】:2015-04-26 06:46:56
【问题描述】:
跟进我最近提出的一个问题,其中可能有一些不必要的东西,但示例很小,我想做什么(当然,如果您能想到其他很酷的方法,请分享您的想法),是允许用户使用特定类型激活非虚拟非接口关联子方法(请让我们专注于如何而不是为什么:))。
我的最后一个错误涉及成员函数签名而不是实际选择,我不知道如何允许完美转发,我尝试了当前无法工作的解决方案(副本),我也尝试过转移Args_t&& 和转发,这也不起作用,关于如何正确传输成员函数的任何建议?我怀疑激活函数定义是错误的......
我已经添加了一个演示编译错误的代码,您也可以将 activate Args_t 输入参数更改为 Args_t&& 然后 forward(args)... 以查看第二个...
谢谢。
struct Type {
enum Value {
One,
Two
};
};
struct A {};
template<typename Type_t, typename R, typename... Args_t>
auto activate(R (Type_t::* f)(Args_t...), A& parent, Args_t... args) -> R // args&& won't comppile either..
{ return (static_cast<Type_t&>(parent).*f)(args...); }
template<typename Type_t, typename R, typename... Args_t>
auto activate(R (Type_t::* f)(Args_t...) const, A const& parent, Args_t... args) -> R
{ return (static_cast<Type_t const&>(parent).*f)(args...); }
struct NonCopyable { public: NonCopyable() {} private: NonCopyable(NonCopyable const& other) {} };
struct B : public A { NonCopyable& foo(NonCopyable& other, bool test) { return other; } };
struct C : public A { NonCopyable& foo(NonCopyable& other, bool test) { return other; } }; // does something else obviously...
#define FuncSelect0(type, parent, func) \
type == Type::One? activate<B>(&B::func, parent) : \
activate<C>(&C::func, parent)
#define FuncSelect1(type, parent, func, arg1) \
type == Type::One? activate<B>(&B::func, parent, arg1) : \
activate<C>(&C::func, parent, arg1)
#define FuncSelect2(type, parent, func, arg1, arg2) \
type == Type::One? activate<B>(&B::func, parent, arg1, arg2) : \
activate<C>(&C::func, parent, arg1, arg2)
#define GET_FS(_1,_2, _3, _4, _5, NAME,...) NAME
#define FuncSelect(...) (GET_FS(__VA_ARGS__, FuncSelect2, FuncSelect1, FuncSelect0)(__VA_ARGS__))
int main() {
NonCopyable n;
bool t;
A* a = new B;
NonCopyable& c = FuncSelect(Type::One, *a, foo, n, t);
delete a;
return 0;
}
【问题讨论】:
-
这两个分支的区别在哪里?
type == Type::One? activate<B>(&B::func, parent) : activate<B>(&B::func, parent) -
应该是里面的模板,没有注意到,因为它只是例如修改过的,谢谢。
-
delete a;导致未定义的行为。在实践中,它通常会破坏堆。 -
这只是一个示例代码,可以删除它............
-
类
A没有虚拟析构函数,因此不会调用a指向的B实例的析构函数。形式上,这会导致未定义的行为,尽管我不同意在这种情况下它应该破坏堆。
标签: c++ templates variadic-templates member-functions