Use of funcName() before deduction of auto — why in one case but not the other?

旧时模样 提交于 2019-12-12 18:33:55

问题


Consider the following code:

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

If I try to compile it as is, gcc tells me

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&){}
 ^

But if I move the conde of lambda out of the lambda or replace call of entryBAD with entryOK, for some reason compilation succeeds. Same success if I move definition of entryBAD out of namespace Test.

Also, clang++ 3.6 compiles in all cases without complaints.

Is gcc right or is it a bug in it? If gcc is right, then what's wrong with the code?

来源:https://stackoverflow.com/questions/33438813/use-of-funcname-before-deduction-of-auto-why-in-one-case-but-not-the-other

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!