C++ g++;5.2-使用整数文本调用模板参数包时出现Wuninitialized警告

C++ g++;5.2-使用整数文本调用模板参数包时出现Wuninitialized警告,c++,g++,c++14,clang++,C++,G++,C++14,Clang++,看过之后,我尝试了这个代码 #include <iostream> #include <utility> template <typename Fun, typename... Param> auto generic_bind(Fun fun, Param&&... param) { return [fun, &param...] (auto&&... x) { return fun(s

看过之后,我尝试了这个代码

#include <iostream>
#include <utility>

template <typename Fun, typename... Param>
auto generic_bind(Fun fun, Param&&... param)
{
    return [fun, &param...] (auto&&... x)
    {
        return fun(std::forward<Param>(param)... , 
                   std::forward<decltype(x)>(x)...);
    };  
}

int demo(int a, int b, int c) { return a * b + c; }

int main()
{
    // does work with int variables
    int a = 11, b = 22, c = 33;
    auto f1 = generic_bind(demo, a); 
    auto f2 = generic_bind(f1, b);
    std::cout << f1(b, c) << f2(33); // both result in 275
}
使用
clang++-Wall
时,两者都正常工作,但GNU g++5.2会创建一个-Wuninitialized警告:

main.cpp: In function 'int main()':
main.cpp:14:42: warning: '<anonymous>' is used uninitialized in this function [-Wuninitialized]
int demo(int a, int b, int c) { return a * b + c; }
                                         ^
main.cpp:27:31: note: '<anonymous>' was declared here
  auto f2 = generic_bind(f1, 22);
                               ^
main.cpp:14:42: warning: '<anonymous>' is used uninitialized in this function [-Wuninitialized]
int demo(int a, int b, int c) { return a * b + c; }
                                         ^
main.cpp:26:36: note: '<anonymous>' was declared here
     auto f1 = generic_bind(demo, 11); 
main.cpp:在函数“int main()”中:

main.cpp:14:42:警告:')。在C++14上哪个编译器是正确的?

程序有未定义的行为,因此任何事情都可能发生,因此可以说这两个编译器都是正确的!GCC的警告是有问题的有用线索,即使它们没有解释确切的问题

使用整型文字时,会导致创建临时
int
对象,并且
参数&&
引用参数会绑定到这些临时右值。然后,lambda使用引用捕获,因此返回的闭包包含对临时对象的引用

这些临时变量在完整表达式的末尾超出范围,即在调用
generic\u bind
后的分号处。这意味着,当您调用
f1
f2
时,您将读取悬挂引用,这是一种未定义的行为


在原始代码中,
Params&
参数绑定到自动变量
a
b
c
,然后闭包包含对这些相同对象的引用,当调用
f1
f2
时,它们仍然在范围内。因此,原始代码是正常的(尽管如果
f1
f2
转义到一个更大的范围,并超过
a
b
c
,您也会遇到同样的问题)。

generic\u bind
引用其参数,这些参数是在对generic\u bind的调用中创建的临时变量,它们超出了范围,所以GCC似乎是对的。
main.cpp: In function 'int main()':
main.cpp:14:42: warning: '<anonymous>' is used uninitialized in this function [-Wuninitialized]
int demo(int a, int b, int c) { return a * b + c; }
                                         ^
main.cpp:27:31: note: '<anonymous>' was declared here
  auto f2 = generic_bind(f1, 22);
                               ^
main.cpp:14:42: warning: '<anonymous>' is used uninitialized in this function [-Wuninitialized]
int demo(int a, int b, int c) { return a * b + c; }
                                         ^
main.cpp:26:36: note: '<anonymous>' was declared here
     auto f1 = generic_bind(demo, 11);