在扣除auto之前使用funcName() - 为什么在一种情况下而不是另一种情况?

时间:2015-10-30 14:52:35

标签: c++ templates lambda argument-dependent-lookup

请考虑以下代码:

#include <unordered_map>
#include <tuple>

namespace Test
{
template<typename State>
struct StateTableEntry
{
    State state;
};
template<typename State>
using StateRow = std::unordered_map<int,StateTableEntry<State>>;

template<typename StateRowValueType>
auto& entryBAD(StateRowValueType& row)
{ return row.second; }

template<typename StateRowValueType>
auto entryOK(StateRowValueType& row) -> decltype((row.second))
{ return row.second; }
}

template<class T,int I,class O> std::enable_if_t<I==std::tuple_size<T>::value>
for_each_index_of(O&){}
template<class Tuple, int startingIndex=0, class Operation>
std::enable_if_t<startingIndex<std::tuple_size<Tuple>::value>
    for_each_index_of(const Operation& operation)
{
    operation(std::integral_constant<std::size_t,startingIndex>());
    for_each_index_of<Tuple,startingIndex+1>(operation);
}

int main()
{
    for_each_index_of<std::tuple<int>>([](const auto&)
    {
        Test::StateRow<long> stateRow;
        for(auto& rowElement : stateRow)
        {
            auto& state(entryBAD(rowElement).state);
            state=1;
        }
    });
}

如果我按原样编译,gcc会告诉我

test.cpp: In instantiation of ‘main()::<lambda(const auto:1&)> [with auto:1 = std::integral_constant<long unsigned int, 0ul>]’:
test.cpp:29:14:   required from ‘std::enable_if_t<(startingIndex < std::tuple_size<_Tp>::value)> for_each_index_of(const Operation&) [with Tuple = std::tuple<int>; int startingIndex = 0; Operation = main()::<lambda(const auto:1&)>; std::enable_if_t<(startingIndex < std::tuple_size<_Tp>::value)> = void]’
test.cpp:43:6:   required from here
test.cpp:40:44: error: use of ‘template<class StateRowValueType> auto& Test::entryBAD(StateRowValueType&)’ before deduction of ‘auto’
             auto& state(entryBAD(rowElement).state);
                                            ^
test.cpp:40:44: error: use of ‘auto& Test::entryBAD(StateRowValueType&) [with StateRowValueType = std::pair<const int, Test::StateTableEntry<long int> >]’ before deduction of ‘auto’
test.cpp:24:1: error: ‘std::enable_if_t<(I == std::tuple_size<_Tp>::value)> for_each_index_of(O&) [with T = std::tuple<int>; int I = 1; O = const main()::<lambda(const auto:1&)>; std::enable_if_t<(I == std::tuple_size<_Tp>::value)> = void]’, declared using local type ‘const main()::<lambda(const auto:1&)>’, is used but never defined [-fpermissive]
 for_each_index_of(O&){}
 ^

但是如果我将lambda的conde移出lambda或用entryBAD替换entryOK的调用,由于某种原因编译成功。如果我将entryBAD的定义移出namespace Test,也会获得相同的成功。

此外,clang ++ 3.6在所有情况下编译都没有抱怨。

gcc是对的还是它的错误?如果gcc是对的,那么代码有什么问题?

0 个答案:

没有答案