繁体   English   中英

当结构具有该成员时,访问模板函数中的结构成员

[英]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;
}

约束:我不能改变FooBar ,所以我不能例如为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM