C++ 引用的std::tuple无法在clang中编译,但不能在gcc中编译

C++ 引用的std::tuple无法在clang中编译,但不能在gcc中编译,c++,g++,language-lawyer,clang++,C++,G++,Language Lawyer,Clang++,以下代码: using input_t = std::tuple<short, int&, const long&, const double>; int b = 1; int c = 2; input_t t{0, b, c, 3}; struct X { X(int i) { std::cerr << "constructed from " << i << std::endl; } ~X()

以下代码:

using input_t = std::tuple<short, int&, const long&, const double>;
int b = 1;
int c = 2;
input_t t{0, b, c, 3};
struct X
{
   X(int i)
   {
      std::cerr << "constructed from " << i << std::endl;
   }
   ~X() { std::cerr << "destructed\n"; }
};

struct Y
{
   const X& ref_;
   Y(const X& ref) : ref_(ref)
   {
      std::cerr << &ref << std::endl;
   }
};

int main ()
{
   int i = 1;
   Y y(i);
   std::cerr << &y.ref_ << std::endl;
}   
这里哪一个是正确的?我没有看到任何会导致超过
b
c
寿命的情况


考虑以下代码:

using input_t = std::tuple<short, int&, const long&, const double>;
int b = 1;
int c = 2;
input_t t{0, b, c, 3};
struct X
{
   X(int i)
   {
      std::cerr << "constructed from " << i << std::endl;
   }
   ~X() { std::cerr << "destructed\n"; }
};

struct Y
{
   const X& ref_;
   Y(const X& ref) : ref_(ref)
   {
      std::cerr << &ref << std::endl;
   }
};

int main ()
{
   int i = 1;
   Y y(i);
   std::cerr << &y.ref_ << std::endl;
}   
现场演示正在进行中

它在这里用
Y
模拟
std::tuple
。在
Y(i)
中,参数
ref
绑定到类型为
X
的临时变量。但是当
ref
参数的生存期结束时,这个临时变量被破坏。然后,
ref\uu
成为一个悬而未决的引用,正如@rafix07在一篇评论中指出的那样

因此,以这样的方式初始化引用类型的元组成员并导致绑定到临时对象是没有意义的。问题是编译器是否需要在此处发出诊断。我认为没有必要,我也没有看到任何相关信息

它只是说,将
转发作为元组

构造
t
中参数的引用元组,该元组适合作为参数转发到函数由于结果可能包含对临时对象的引用,程序应确保此函数的返回值不超过其任何参数


但是
tuple
(“direct”)构造函数的定义中没有相同的措辞。

如何将
int
绑定到
long
?通过将
int
升级为
long
创建临时实例,然后将此临时实例绑定到
const long&
。你有悬而未决的参考资料。将此行添加到代码:
std::cout@rafix07 ahhhh!完美的那么GCC在这里错了吗?我想是的。@rafix07完全正确,但它不会告诉您编译器是否应该在编译时拒绝代码。只要你不直接使用
std::get(t)
,你就没有UB。你在这里说的是对的,但是clang编译这个例子没有问题,所以这并没有回答实际的问题,可能是特定于
元组的。@Holt同意,我也意识到了这一点。如果我发现任何相关信息,我将尝试深入挖掘并更新我的答案。