问题
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