[英]Accessing struct member in a template function, when the struct has that member
I'd like to implement this functionality with C++ templates as nicely as possible.我想用 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;
}
Constraints: I can not alter Foo
or Bar
, so I can't for example add abstract interface superclass for Foo
.约束:我不能改变
Foo
或Bar
,所以我不能例如为Foo
添加抽象接口超类。 I don't want to specialize the function specifically for any named class either, and I don't want to repeat any logic code.我也不想专门为任何命名类专门化该函数,也不想重复任何逻辑代码。
My current, rather dumb solution is to have template <typename T> int helperFunc(const T &item, int y = 0) {...};
我目前相当愚蠢的解决方案是让
template <typename T> int helperFunc(const T &item, int y = 0) {...};
, and then for a Foo
call it like helperFunct(aFoo, aFoo.y)
, which works for my use case, but is not very nice. ,然后对于
Foo
调用它像helperFunct(aFoo, aFoo.y)
,这适用于我的用例,但不是很好。 I'd like to put the decision to use y
inside the template.我想将使用
y
的决定放在模板中。 I tried to find something applicable from here , but couldn't really come up with a way to use any of that to achieve the above.我试图从这里找到一些适用的东西,但无法真正想出一种方法来使用其中任何一种来实现上述目标。
You can use SFINAE on function overloads to check for the existence of y
, then use if-constexpr
:您可以在函数重载上使用 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;
}
You can make type trait to check whether the type has the member y
or not.您可以使用 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 {};
then you can apply constexpr if (since C++17).那么你可以应用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.