简体   繁体   English

C ++ - 迭代元组和类型与常量参数的分辨率

[英]C++ - Iterating over a tuple & resolution of type vs constant parameters

I'm currently in the process of writing arithmetic operator overloads for tuples. 我目前正在为元组编写算术运算符重载。 The operator iterates over the tuple to perform the operation on each of its individual element. 运算符迭代元组以对其每个元素执行操作。 Here is the definition for operator +=: 这是operator + =的定义:

template< typename... Ts, std::size_t I = 0 >
inline typename std::enable_if< I == sizeof... (Ts), std::tuple< Ts... >& >::type operator +=(std::tuple< Ts... >& lhs, const std::tuple< Ts... >& rhs)
{
    return lhs;
}

template< typename... Ts, std::size_t I = 0 >
inline typename std::enable_if< I != sizeof... (Ts), std::tuple< Ts... >& >::type operator +=(std::tuple< Ts... >& lhs, const std::tuple< Ts... >& rhs)
{
    std::get< I >(lhs) += std::get< I >(rhs);
    return operator +=< Ts..., I + 1 >(lhs, rhs);
}

Unfortunately, when I attempt to call the operator, GCC 4.6 cannot decide which overload it should use. 不幸的是,当我试图调用运算符时,GCC 4.6无法决定它应该使用哪个超载。 For example: 例如:

std::tuple< int, int, int, int > a = std::make_tuple(1, 2, 3, 4), b = std::make_tuple(5, 6, 7, 8);
a += b;

Yields the following error: 产生以下错误:

:/Workspace/raster/main.cpp:833:7:   instantiated from here
C:/Workspace/raster/main.cpp:809:45: error: no matching function for call to 'operator+=(std::tuple<int, int, int, int>&, const std::tuple<int, int, int, int>&)'
C:/Workspace/raster/main.cpp:809:45: note: candidates are:
C:/Workspace/raster/main.cpp:800:151: note: template<class ... Ts, unsigned int I> typename std::enable_if<(I == sizeof (Ts ...)), std::tuple<_TElements ...>&>::type operator+=(std::tuple<_TElements ...>&, const std::tuple<_TElements ...>&)
C:/Workspace/raster/main.cpp:806:83: note: template<class ... Ts, unsigned int I> typename std::enable_if<(I != sizeof (Ts ...)), std::tuple<_TElements ...>&>::type operator+=(std::tuple<_TElements ...>&, const std::tuple<_TElements ...>&)

Which is strange since the std::enable_if condition should reject the inappropriate call. 这很奇怪,因为std::enable_if条件应该拒绝不适当的调用。 For now, I have the following workaround which was actually my prior implementation. 现在,我有以下解决方法,这实际上是我之前的实现。 The above version is in fact a simplification attempt. 以上版本实际上是一种简化尝试。

template< std::size_t I, typename... Ts >
inline typename std::enable_if< I == sizeof... (Ts), std::tuple< Ts... >& >::type assignadd_impl(std::tuple< Ts... >& lhs, const std::tuple< Ts... >& rhs)
{
    return lhs;
}

template< std::size_t I, typename... Ts >
inline typename std::enable_if< I != sizeof... (Ts), std::tuple< Ts... >& >::type assignadd_impl(std::tuple< Ts... >& lhs, const std::tuple< Ts... >& rhs)
{
    std::get< I >(lhs) += std::get< I >(rhs);
    return assignadd_impl< I + 1, Ts... >(lhs, rhs);
}

template< typename... Ts >
inline std::tuple< Ts... >& operator +=(std::tuple< Ts... >& lhs, const std::tuple< Ts... >& rhs)
{
    return assignadd_impl< 0, Ts... >(lhs, rhs);
}

This compiles and works as expected. 这编译并按预期工作。 Why does the simplified version refuse to compile? 为什么简化版本拒绝编译? Thanks. 谢谢。

Using explicitly specified template arguments to a function or class template requires that any template parameter packs appear at the end of the overall template parameter list. 对函数或类模板使用显式指定的模板参数要求任何模板参数包出现在整个模板参数列表的末尾。 Moving Ts... to the end of the template parameter lists and changing the calls appropriately makes the code work. Ts...移动到模板参数列表的末尾并相应地更改调用使代码工作。 Section 14.8.2.1 of the current C++0x draft states that parameter packs that are not at the end of the template parameter list cannot be deduced from a function call (which makes your original code fail), but explicitly specifying all of the template arguments to operator+= in all cases still causes a SFINAE error. 当前C ++ 0x草案的第14.8.2.1节规定,不能从函数调用推导出不在模板参数列表末尾的参数包(这会使原始代码失败),但明确指定所有模板在所有情况下, operator+=参数仍会导致SFINAE错误。 A previous question has a link to the exact text forbidding it; 上一个问题有一个指向禁止它的确切文本的链接; IBM's documentation says that it is an error as well. IBM的文档说这也是一个错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM