我有错误,当我试图创建包装所有模板类方法以进行日志记录的方法时。
我固定了我的类声明和方法 log_call 是我尝试过的。如何解决此问题,或者可能还有其他可行的解决方案。我想在调用任何其他方法时调用 log() 函数,而无需在每个方法中对其进行硬编码。
template <class DataUnit>
class ModelManager {
public:
ModelManager(std::string source, std::string path);
std::vector<DataUnit> copy();
std::vector<DataUnit> copy(std::map<std::string, std::string> by_what);
template <typename R, typename... TArgs>
R log_call(R (ModelManager<DataUnit>::*f)(TArgs...), const TArgs... args) {
this->log();
return (this->*f)(args...);
}
private:
void log() {
std::cout << "Called!" << "\n";
};
};
然后我尝试按照下面的方式使用它,并得到一个错误。
ModelManager<Client> manager("txt", "clients.txt");
manager.log_call(&ModelManager<Client>::copy);
实际错误
models/base_model_manager.h:47:11: note: template argument deduction/substitution failed:
main.cpp:22:34: note: couldn't deduce template parameter 'R'
22 | std::cout << manager.log_call(&ModelManager<Client>::copy) << "\n";
| ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
实际的错误是歧义:
unresolved overloaded function type
,但你只显示了错误消息的四个部分中的最后一个。
<source>:68:21: error: no matching function for call to 'ModelManager<Client>::log_call(<unresolved overloaded function type>)'
68 | manager.log_call(&ModelManager<Client>::copy);
| ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:40:11: note: candidate: 'template<class R, class ... TArgs> R ModelManager<DataUnit>::log_call(R (ModelManager<DataUnit>::*)(TArgs ...), const TArgs ...) [with R = R; TArgs = {TArgs ...}; DataUnit = Client]'
40 | R log_call(R (ModelManager<DataUnit>::*f)(TArgs...), const TArgs... args) {
| ^~~~~~~~
<source>:40:11: note: template argument deduction/substitution failed:
<source>:68:21: note: couldn't deduce template parameter 'R'
68 | manager.log_call(&ModelManager<Client>::copy);
| ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
你有两个重载函数
ModelManager<T>::copy
,你要传递哪个&ModelManager<Client>::copy
给log_call
?
正确的代码:
manager.log_call(static_cast<std::vector<Client>(ModelManager<Client>::*)()>(
&ModelManager<Client>::copy));