![](/img/trans.png)
[英]accessing templated member function of an object that is a member of a struct
[英]Accessing struct member in a template function, when the struct has that member
我想用 C++ 模板尽可能好地实现这个功能。
struct Foo {
int x = 0;
int y = 0;
};
struct Bar {
int x = 1;
};
// I want to call this function for both Foo and Bar instances
template <typename T>
int helperFunc(const T &item) {
// many lines of code I don't want to repeat
int result = item.x;
result += item.x;
result *= item.x;
// only do code below if item has y
result += item.y;
return result;
}
约束:我不能改变Foo
或Bar
,所以我不能例如为Foo
添加抽象接口超类。 我也不想专门为任何命名类专门化该函数,也不想重复任何逻辑代码。
我目前相当愚蠢的解决方案是让template <typename T> int helperFunc(const T &item, int y = 0) {...};
,然后对于Foo
调用它像helperFunct(aFoo, aFoo.y)
,这适用于我的用例,但不是很好。 我想将使用y
的决定放在模板中。 我试图从这里找到一些适用的东西,但无法真正想出一种方法来使用其中任何一种来实现上述目标。
您可以在函数重载上使用 SFINAE 来检查y
是否存在,然后使用if-constexpr
:
template <typename T>
std::true_type hasY_ (decltype(std::declval<T> ().y)*);
template <typename T>
std::false_type hasY_ (...);
template <typename T>
static constexpr bool hasY = decltype(hasY_<T>(0))::value;
// I want to call this function for both Foo and Bar instances
template <typename T>
int helperFunc(const T &item) {
// many lines of code I don't want to repeat
int result = item.x;
result += item.x;
result *= item.x;
// only do code below if item has y
if constexpr (hasY<T>)
result += item.y;
return result;
}
您可以使用 type trait 来检查该类型是否具有成员y
。
template <typename T, typename = void>
struct has_y : std::false_type {};
template <typename T>
struct has_y<T, std::void_t<decltype(std::declval<T>().y)>>
: std::true_type {};
那么你可以应用constexpr if (C++17 起)。
if constexpr (has_y<T>::value) // only do code below if item has y
result += item.y;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.