代码如下。看起来很简单,但是得到一些我无法找到错误的编译错误。
#define ENABLE_IF(Condition, Type) typename enable_if < (Condition), Type>::type
template<size_t I = 0, class... Ts>
ENABLE_IF(I == sizeof...(Ts), void) read(QDataStream& in, tuple<Ts...>& t)
{}
template<size_t I = 0, class... Ts>
ENABLE_IF(I < sizeof...(Ts), void) read(QDataStream& in, tuple<Ts...>& t)
{
in >> std::get<I>(t);
read<I + 1>(in, t);
}
lat语句出错:error C2770: invalid explicit template argument(s) for 'enable_if<I<0x01,void>::type read(QDataStream &,std::tuple<_Types1...> &)'
经过更多测试,结果证明以下代码没问题
template<size_t I = 0, class Tuple>
ENABLE_IF(I == tuple_size<Tuple>::value, void) read(QDataStream& in, Tuple& t)
{}
template<size_t I = 0, class Tuple>
ENABLE_IF(I < tuple_size<Tuple>::value, void) read(QDataStream& in, Tuple& t)
{
in >> std::get<I>(t);
read<I + 1>(in, t);
}
这使用元组类型作为模板参数而不是其元素类型包。是什么原因? VS2013的编译错误?
与其他编译器一起测试。原始代码没问题。我认为这是一个VS2013错误。 : - (
答案 0 :(得分:1)
这很简单!您的主模板不仅有一个参数。你应该通过第二个参数Ts ......:
read<I + 1, Ts...>(in, t);
反向订单阅读
#include <iostream>
#include <sstream>
#include <tuple>
template<size_t I, typename... Ts>
struct reader
{
static void read(std::istream& i, std::tuple<Ts...>& t)
{
i >> std::get<I>(t);
reader<I - 1, Ts...>::read(i, t);
}
};
template<typename... Ts>
struct reader<0, Ts...>
{
static void read(std::istream& i, std::tuple<Ts...>& t)
{
i >> std::get<0>(t);
}
};
template<typename... Ts>
void read(std::istream& i, std::tuple<Ts...>& t)
{
reader<sizeof...(Ts) - 1, Ts...>::read(i, t);
}
int main()
{
std::istringstream istr("1 2");
std::tuple<int, double> t;
read(istr, t);
}
答案 1 :(得分:0)
我也想这样做,所以我写了这篇文章(C ++ 17仅由if constexpr
引起):
#include <tuple>
#include <iostream>
template<class Head, class... Tail>
std::tuple<Head, Tail...> tuple_read_impl(std::istream& is) {
Head val;
is >> val;
if constexpr (sizeof...(Tail) == 0) // this was the last tuple value
return std::tuple{val};
else
return std::tuple_cat(std::tuple{val}, tuple_read_impl<Tail...>(is));
}
template<class... Types>
std::istream& operator>>(std::istream& is, std::tuple<Types...> &tup) {
tup = tuple_read_impl<Types...>(is);
return is;
}
int main ()
{
std::tuple<size_t, size_t> tup;
std::cin >> tup;
auto [x, y] = tup;
std::cout << x << ' ' << y;
}