假设我在C ++中有类似以下的函数:
template<typename Container>
void doNothing(Container * container) {
for (auto element: container) {
std::cout << element;
}
}
是否可以&#34;模拟&#34;可以通过将this
传递给它而不是第一个参数来实现此功能的各种类的方法。 (例如,像std :: vector,std :: string ......等类。)
所以基本上不必将其用作:
std::vector<double> a{1, 2, 0.5}:
doNothing(a);
我可以称之为:
std::vector<double> a{1, 2, 0.5}:
a.doNothing();
答案 0 :(得分:1)
您始终可以通过传递对象的this
指针来模拟成员函数。
毕竟,所有编译器都在为正确的成员函数做些事情(将this
作为隐藏的第一个参数传递)。
因此,如果您希望函数foo
的行为类似于成员并对Bar
类型的对象(忽略此处为private / protected)进行操作,那么您可以将其声明为:
void foo(Bar* self);
并将其称为
Bar b;
foo(&b);
(或来自Bar
成员:foo(this);
)
然后它将能够访问b
的成员并通过解除引用self
指针来调用其函数。
答案 1 :(得分:1)
不,你不能这样做。
调用this
中的a.b()
参数是隐式的,并且无法伪造隐式参数。
除非a.b()
是成员,否则您无法使用b
语法。
答案 2 :(得分:1)
template<class F>
struct poly_mem_ptr_t{
F f;
template<class T>
friend auto operator->*( T* t, poly_mem_ptr_t self )const{
return
[t, f=self.f](auto&&...args)->decltype(auto){
return f(t, decltype(args)(args)...);
};
}
template<class T>
friend auto operator->*( T& t, poly_mem_ptr_t self )const{
return std::addressof(t)->*self;
}
};
template<class F>
poly_mem_ptr_t<F> poly_mem_ptr(F f){ return {std::move(f)}; }
样品使用:
auto do_nothing = poly_mem_ptr([](auto* ptr){ doNothing(ptr); });
std::vector<int> v={1,2,3};
(v->*do_nothing)();
不完全是你想要的,但是关闭。
作为一项好处,您可以添加
template<class...Ts>
friend decltype(auto) operator->*( std::variant<Ts...>& var, poly_mem_ptr_t self )const{
return [&var, f=self.f](auto&&...args) {
return std::visit( [&](auto&&t)->decltype(auto){
return f( decltype(t)(t), decltype(args)(args)... );
}, var);
};
}
现在您可以使用std::variant
并将这些poly_mem_ptr
用作访问者。
通过一些工作,您还可以设置增强的std::any
来支持一组固定的poly_mem_ptr
。