簡體   English   中英

缺少表達方式SFINAE的解決方法

[英]Workaround for lack of expression SFINAE

我試圖為std::tuple中的每個值調用一個函數,當然沒有辦法迭代一個元組,因此我求助於使用在元組上迭代所討論的模板技術

但是,我使用的是Visual Studio 2013,它不支持表達式SFINAE,因此該代碼將不起作用。 我試圖基於常數(例如5、4、3、2、1、0)對模板進行部分專業化處理,但沒有取得任何成功。 我當然不是模板專家,所以我希望有人可以幫助我。 我的表達式SFINAE代碼如下。

#include <iostream>
#include <tuple>

using namespace std;

struct ArgPush {
    void push(bool x) {}
    void push(int x) {}
    void push(double x) {}
    void push(const char* x) {}
    void push(const std::string& x) {}

    template<std::size_t I = 0, typename... Tp>
    inline typename std::enable_if<I == sizeof...(Tp), void>::type
        push_tuple(const std::tuple<Tp...>& t)
    { }

    template<std::size_t I = 0, typename... Tp>
    inline typename std::enable_if<I < sizeof...(Tp), void>::type
        push_tuple(const std::tuple<Tp...>& t)
    {
        push(std::get<I>(t));
        push_tuple<I + 1, Tp...>(t);
    }
};

int main() {
    ArgPush().push_tuple(std::make_tuple(1,2,3,4));
    ArgPush().push_tuple(std::make_tuple("hello", "msvc makes me sad", 4, true));
    return 0;
}

MSVC不喜歡在enable_if中進行相等性比較。 因此,將它們從那里移到幫助器模板。 然后,您的代碼將在VS2013上編譯。

template<std::size_t I, typename... Tp>
struct comparator
{
    static const bool value = (I < sizeof...(Tp));
};

template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<!comparator<I, Tp...>::value>::type
    push_tuple(const std::tuple<Tp...>& t)
{ }

template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<comparator<I, Tp...>::value>::type
    push_tuple(const std::tuple<Tp...>& t)
{
    push(std::get<I>(t));
    push_tuple<I + 1, Tp...>(t);
}

您可以使用部分專業化來代替SFINAE:

template <std::size_t N>
struct helper
{
    template <typename T>
    static void push(T&& v)
    {
        // do something
    }
    template <typename ...Types>
    static void push_tuple(const std::tuple<Types...>& t)
    {
        push(std::get<sizeof...(Types) - N>(t));
        helper<N - 1>::push_tuple(t);
    }
};

template <>
struct helper<0>
{
    template <typename ...Types>
    static void push_tuple(const std::tuple<Types...>&)
    {
        // nothing (end of iteration)
    }
};

template <typename ...Types>
void push_tuple(const std::tuple<Types...>& t)
{
    helper<sizeof...(Types)>::push_tuple(t);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM