![](/img/trans.png)
[英]No matching function for call in class template specialization for a pointer type
[英]Matching Pointer to members and its type as template parametes
鑒於此代碼
struct data {
int velocity;
};
template <typename Data>
class Collector {
// ...
public:
void add(const Data& data) {}
template <typename T>
T average1(T Data::*field) const {
return T{}; // Some calculation here
}
template <T Data::*field>
T average2() const {
return T{}; // Some calculation here
}
};
void foo() {
Collector<data> collector;
// I have no problem handling the average by sending member as parameter
auto ok = collector.average1(&data::velocity);
// But compilation here fails
auto error = collector.average2<&data::velocity>();
}
我的目的是用模板參數替換將成員傳遞給函數的指針,但不能同時匹配成員類型和成員,我可以做類似的事情
template <typename T, T Data::*field>
T average2() const {
return T{}; // Some calculation here
}
但后來我必須調用
auto error = collector.average2<int, &data::velocity>();
這很丑陋而且似乎沒有必要
您對如何解決此問題或收集此類數據的更好方法有什么想法嗎?
提前致謝
在 C++17 中,您可以通過將 value 模板參數擴展為auto
並稍后解析T
來使模板化版本工作,例如使用decltype()
。
#include <type_traits>
template <typename Data>
class Collector {
// ...
public:
template <auto field>
auto average2() const {
using T = decltype(std::declval<Data>().*field);
return T{}; // Some calculation here
}
};
void foo() {
Collector<data> collector;
// Works perfectly fine
auto error = collector.average2<&data::velocity>();
}
在 C++20 中,您可以通過將field
限制為Data
成員指針來使這個更清晰。 這將為您提供更嚴格的重載解決方案以及更好的錯誤消息。
#include <type_traits>
template<typename PtrT, typename ObjT>
concept MemberObjectPointerFor = std::is_member_object_pointer_v<PtrT> &&
requires(PtrT ptr, ObjT& obj) {
{ obj.*ptr };
};
template <typename Data>
class Collector {
// ...
public:
template <MemberObjectPointerFor<Data> auto field>
auto average2() const {
using T = decltype(std::declval<Data>().*field);
return T{}; // Some calculation here
}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.