繁体   English   中英

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

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

我目前正在为元组编写算术运算符重载。 运算符迭代元组以对其每个元素执行操作。 这是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);
}

不幸的是,当我试图调用运算符时,GCC 4.6无法决定它应该使用哪个超载。 例如:

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

产生以下错误:

:/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 ...>&)

这很奇怪,因为std::enable_if条件应该拒绝不适当的调用。 现在,我有以下解决方法,这实际上是我之前的实现。 以上版本实际上是一种简化尝试。

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);
}

这编译并按预期工作。 为什么简化版本拒绝编译? 谢谢。

对函数或类模板使用显式指定的模板参数要求任何模板参数包出现在整个模板参数列表的末尾。 Ts...移动到模板参数列表的末尾并相应地更改调用使代码工作。 当前C ++ 0x草案的第14.8.2.1节规定,不能从函数调用推导出不在模板参数列表末尾的参数包(这会使原始代码失败),但明确指定所有模板在所有情况下, operator+=参数仍会导致SFINAE错误。 上一个问题有一个指向禁止它的确切文本的链接; IBM的文档说这也是一个错误。

暂无
暂无

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

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