Re: Warning when using trailing return type and decltype
On 2012-02-15 02:23, Jens Auer wrote:
I am trying to write me a little helper function to reduce a list
using a binary function:
#include<vector>
struct Int
{
explicit Int(int);
};
Int intfunc(Int, Int);
template<typename FwdIt, typename Func, typename T>
auto foldl(FwdIt first, FwdIt last, Func f, T initial) ->
decltype(f(initial, *first))
{
for(; first != last; ++first)
{
initial = f(initial, *first);
}
return initial;
}
Just wondering: Why do you specify the result type as
decltype(f(initial, *first)) here and not T, which the actual value that
you are returning?
// instantiate template to check compilation
void instantiate()
{
std::vector<Int> v;
Int x3 = foldl(v.begin(), v.end(), intfunc, Int(0));
Int x4 = foldl(v.cbegin(), v.cend(), intfunc, Int(0));
}
When I compile this on VC++2010, I get warning:
Warning 1 warning C4172: returning address of local variable or
temporary c:\users\jensa\desktop\vs2010bug\foldl\foldl\foldl.cpp 18
Warning 2 warning C4172: returning address of local variable or
temporary c:\users\jensa\desktop\vs2010bug\foldl\foldl\foldl.cpp 18
g++ 4.6 compiles without these warning, which I think is correct. Can
anybody clarify this for me? We currently have setup our project to
turn warnings like this into errors and I would really like to keep
this setting. The code compiles without warning when I replace the
decltype with the fixed return type Int.
IMO there is nothing wrong in your code, decltype(f(initial, *first))
should be deduced to be equal to Int, which is exactly the same type
that you are returning. Testing with VS2010 it seems that
static_assert(std::is_same<decltype(f(initial, *first)), T>::value,"");
this test fails pointing to the root of the compiler error. It turns
out, that the wrong result
static_assert(std::is_same<decltype(f(initial, *first)), T&>::value,"");
is accepted. This is definitively a compiler error, the function intfunc
returns an Int and this type is required to be returned by decltype.
PS: I have not found such a function in the standard library. If there
is one, I would be happy to know.
Use std::accumulate from <numeric>, it is exactly equal to your foldl
template except for the following differences:
a) The last two function parameters are inverted, and
b) The return type is T, not decltype(f(initial, *first))
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]