假设我们有这样的代码:
template<class CALLBACK>
struct INIFile{
INIFile(CALLBACK &processor) :
processor(processor ){}
bool process(){
// lots of code here,
// call processor
processor(123);
return true;
}
CALLBACK &processor;
};
struct MyProcessor{
void operator()(int val){
// do something
}
};
struct MyConstProcessor{
void operator()(int val) const{ // !!!!!
// do something
}
};
int main(){
MyProcessor p;
INIFile<MyProcessor> ini(p);
ini.process();
// const case:
MyConstProcessor cp;
INIFile<MyConstProcessor> cini(cp);
cini.process();
}
在这两种情况下,INIFile<>::process()
都是非const
成员函数。
如果process()
为const
CALLBACK::operator()
const
,INIFile<>::process()
中没有重复的所有逻辑,是否有一种简单的方法可以使# WEB 0.1
FROM ubuntu:14.04
RUN apt-get update \
&& apt-get install -y \
default-jre \
x11vnc \
xdotool \
xsel \
xvfb \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN DISPLAY=:1.0 \
&& export DISPLAY \
&& mkdir /root/.vnc \
&& x11vnc -storepasswd 1234 /root/.vnc/passwd \
&& Xvfb :1 -screen 0 493x476x8 & \
x11vnc -display :1.0 -usepw -forever &
ENTRYPOINT ["java"]
CMD ["-jar", "/var/bin/program.jar"]
成为docker run \
--name program-jar \
-p 5090:5900 \
-v /var/bin/program-jar/:/var/bin/ \
-d program-jar:0.1
成员函数?
答案 0 :(得分:3)
通过执行以下操作解决了您的问题:
template<class CALLBACK>
struct INIFile{
INIFile(CALLBACK &processor) :
processor(processor){}
template <class T>
bool process_impl(T& processor) const {
// deliberately shadow processor
// reduce likelihood of using member processor, but can use other member variables
// lots of code
processor(123);
return true;
}
bool process() const {
return process_impl(const_cast<const CALLBACK&>(processor));
}
bool process() {
return process_impl(processor);
}
CALLBACK& processor;
};
这当然在技术上会超载process
,但它具有您想要的完全相同的效果。如果processor
的调用操作符不标记为const,并且您尝试通过const引用或对象的const副本调用process
,则会出现编译错误(与你的解决方案不同)。这是因为const
的{{1}}重载被调用,它将process
添加到传入的处理器中,然后处理器上的调用操作符失败。
但是,如果回调确实提供了const
调用操作符,那么任一进程调用都将执行完全相同的操作。这实际上意味着您可以在const
的常规副本上调用process
,这相当于INIFile
process
。
如果回调也会使调用运算符重载,那么此实现将转发到正确的转发,但您没有将其指定为条件。唯一要注意的是,const
永远不应该访问成员变量process_impl
,因为该成员变量将始终是可变的,即即使它不应该调用也会起作用(例如你的解决方案)。我故意暗影试图阻止这一点。这不是那么漂亮,但作为一个实现细节,它并没有那么糟糕,它确实消除了重复。
答案 1 :(得分:0)
我发现的另一种方式,但我不太喜欢使用指针而不是引用。
这是代码。
请注意,在这种特殊情况下,我们根本不需要检查nullptr
。
template<class CALLBACK>
struct INIFile{
INIFile(CALLBACK &processor) :
processor(& processor ){}
bool process() const{
// lots of code here,
// call processor
processor->operator()(123);
return true;
}
CALLBACK *processor;
};