Meta-Programming with a Method Parameter

有些话、适合烂在心里 提交于 2019-12-13 01:23:56

问题


I'm writing a pair wrapper. For the purposes of this question it can be simplified down to:

using namespace std;

template <class T1, class T2>
class myPair {
    pair<T1, T2> member;
public:
    myPair() = default;
    myPair(T1 x, T2 y) : member(make_pair(x, y)) {}
};

I'd like to be able to treat a myPair as an index-able container of size 2. To do this I'd obviously need to write an index operator for myPair. I'd like to do something like this, but my return type will depend upon a method parameter, and I can't use method parameters in meta-programming.

auto myPair::operator[](int index) {
    static_assert(index >= 0 && index < 2, "Index out of range");

    return get<index>(*this);
}

Obviously I could tackle this in the same way that pair does by providing a get function, but I'd like to me able to use the index operator syntax. Is there any way I can specialize a function template or use a method parameter to meta-program a template's return type?


回答1:


It's almost possible. The integer literal can't be used directly as a constant-expression, but it can be wrapped in one, for example a template instantiation.

template <int> struct idx_ {};

template <char... C>
auto operator ""_i () {
    return idx_<(C - '0')...>{};
}

template <class T1, class T2>
class myPair {
    std::pair<T1, T2> member;
public:
    myPair() = default;
    myPair(T1 x, T2 y) : member(std::make_pair(x, y)) {}

    T1 &operator [] (idx_<0>) {
        return member.first;
    }

    T2 &operator [] (idx_<1>) {
        return member.second;
    }
};

int main() {
    myPair<int, std::string> mp(42, "Hi");
    std::cout << mp[0_i] << ", " << mp[1_i] << '\n';
}

Output:

42, Hi

Live on Coliru




回答2:


No, it's not possible. The member function operator[] accepts non-constexpr objects, therefore making a compile time type detection pretty much impossible.

This will also make the static_assert not compile, for the same reason.




回答3:


You may use std::intergral_constant

template <std::size_t N>
const auto& operator[](std::integral_constant<std::size_t, N>) const {
    static_assert(N < 2, "Index out of range");

    return std::get<N>(member);
}

template <std::size_t N>
auto& operator[](std::integral_constant<std::size_t, N>) {
    static_assert(N < 2, "Index out of range");

    return std::get<N>(member);
}

Live Demo



来源:https://stackoverflow.com/questions/31922056/meta-programming-with-a-method-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!