GCC元组"无效使用不完整类型"

时间:2016-07-21 11:55:57

标签: c++ templates gcc

我有一个代码:

#include <tuple>
#include <utility> 
#include <iostream>

template<int ...> struct seq {};
template<int N, int ...S> struct gens : gens<N - 1, N - 1, S...> {};
template<int ...S> struct gens<0, S...> { typedef seq<S...> type; };

template<typename ValueType>
bool get_value(ValueType& value, int index) {
    //just for test
    value = 100;
    return true;
}


template<>
bool get_value(const char*& value, int index) {
    //just for test
    value = "Hello?";
    return true;
}

template<int index, std::size_t remaining, typename... Args>
struct arg_helper {
    inline static bool
    get_args(std::tuple<Args...>& t) {
        if (get_value(std::get<index>(t), index)) {
            return arg_helper<index + 1, remaining - 1, Args...>::get_args(t);
        }
        else {
            return false;
        }
        return true;
    }
};


template<std::size_t index, typename... Args>
struct arg_helper<index, 0, Args... > {
    inline static bool
    get_args(std::tuple<Args...>& t) {
        return true;
    }
};


template<typename R, typename... Args, int ...S>
void callFunc(R(func)(Args...), seq<S...>, std::tuple<Args...>& tup) {
    func(std::get<S>(tup) ...);
}

template<typename R, typename... Args>
void TestFunc(R(func)(Args...)) {
    std::tuple<Args...> tup;

    arg_helper<0, sizeof ...(Args), Args...>::get_args(tup);

    callFunc(func, typename gens<sizeof...(Args)>::type(), tup);
}

static void FuncA(int test, const char* str) {
    std::cout << "test func" << test << str << std::endl;
}


int main() {
    TestFunc(FuncA);
    return 0;
}

它可以在MSVC2013上运行,但在GCC上的编译器错误:

arg_helper<0, sizeof ...(Args), Args...>::get_args(tup);

我做错了什么?

顺便说一句:我知道iterate over tuple 它可以在gcc上运行,但似乎不适用于MSVC2013

1 个答案:

答案 0 :(得分:2)

这似乎是因为您的非类型模板参数中的intsize_t不匹配。将它们全部更改为size_t,您就可以了:

Demo (GCC)

Demo (Clang)

#include <tuple>
#include <utility> 
#include <iostream>

template<size_t ...> struct seq {};
template<size_t N, size_t ...S> struct gens : gens<N - 1, N - 1, S...> {};
template<size_t ...S> struct gens<0, S...> { typedef seq<S...> type; };

template<typename ValueType>
bool get_value(ValueType& value, size_t index) {
    //just for test
    value = 100;
    return true;
}


template<>
bool get_value(const char*& value, size_t index) {
    //just for test
    value = "Hello?";
    return true;
}

template<size_t index, std::size_t remaining, typename... Args>
struct arg_helper {
    static bool
    get_args(std::tuple<Args...>& t) {
        if (get_value(std::get<index>(t), index)) {
            return arg_helper<index + 1, remaining - 1, Args...>::get_args(t);
        }
        else {
            return false;
        }
        return true;
    }
};

template<std::size_t index, typename... Args>
struct arg_helper<index, 0, Args... > {
    static bool
    get_args(std::tuple<Args...>& t) {
        return true;
    }
};


template<typename R, typename... Args, size_t ...S>
void callFunc(R(func)(Args...), seq<S...>, std::tuple<Args...>& tup) {
    func(std::get<S>(tup) ...);
}

template<typename R, typename... Args>
void TestFunc(R(func)(Args...)) {
    std::tuple<Args...> tup;

    arg_helper<0, sizeof ...(Args), Args...>::get_args(tup);

    callFunc(func, typename gens<sizeof...(Args)>::type(), tup);
}

void FuncA(int test, const char* str) {
    std::cout << "test func" << test << str << std::endl;
}


int main() {
    TestFunc(FuncA);
    return 0;
}