c++ - 如果元组足够大,使用 SFINAE 启用方法

标签 c++

我有一个包含元组的类:

template <typename ... Args>
struct Point {
    std::tuple<Args...> data;
    ... 
};

在内部,我需要一些创建数据 View 的方法。例如,当数据具有一维或多维时,最好使用名为 x 的方法。和 y拉出第一个和第二个元素:

template <typename ... Args>
struct Point {

    std::tuple<Args...> data;

    using value_type = decltype(data);

    template<typename T = typename std::tuple_element<0, value_type>::type>
    T &x() {
        return std::get<0>(data);
    }

    template<typename T = typename std::tuple_element<1, value_type>::type>
    T &y() {
        return std::get<1>(data);
    }
};

问题是元组大小。当元组大小小于访问器时,我无法弄清楚如何使用 SFINAE 不提供此方法。例如,如果您创建多于 1 维的点(例如 Point<float,int> ),则上述类可以很好地工作。但是,如果您尝试创建 Point<float>,代码将无法编译。 .具体来说,对于 GCC 8.2,我收到编译器错误:

no type named 'type' in 'struct std::tuple_element<1, std::tuple<float> >'

我也试过这样的成语:

auto y() -> typename std::tuple_element<1, value_type>::type {
    return std::get<1>(data);
}

但我得到了同样的编译器错误。

最佳答案

SFINAE 中的“S”代表“替换”。因此,您需要确保您的检查发生在替换时间。您可以通过引入一个默认为 value_type 的额外模板参数来做到这一点:

template<typename U = value_type, typename T = typename std::tuple_element<0, U>::type>
T &x() {
    return std::get<0>(data);
}

template<typename U = value_type, typename T = typename std::tuple_element<1, U>::type>
T &y() {
    return std::get<1>(data);
}

live example on godbolt.org

关于c++ - 如果元组足够大,使用 SFINAE 启用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54669322/

相关文章:

c++ - 内存引用发送到双指针

C++ 将对基指针的引用转换为对派生指针的引用

c++ - 如何通过key从map中获取值

C++抽象类无法实例化

c++ - 使用 QPrinter::HighResolution 不打印

C++11 可变参数模板和逗号分隔表达式等价

c++ - NULL 指针赋值错误

c++ - 如何配置 VS 2010 来创建一个利用其他 DLL 的 DLL

java - Mac笔记本电脑使用和开发讨论?

c++ - std::list 中 end() 之后的下一个迭代器