通过尝试解决这个问题,有些事让我感到奇怪.请考虑以下代码:
template <typename T>
struct foo
{
foo(T const& x) : data(x) {}
T data;
};
Run Code Online (Sandbox Code Playgroud)
似乎我可以构造一个foo<T const&>没有错误的类型的对象,假设T const& const&被理解为T const&.
这似乎也被称为参考崩溃,但我之前从未听过这个术语(参见链接问题中的评论).
这是普遍的吗?这是标准吗?
下面的代码编译(gcc 4.7.2或icc 13)并产生"1 2"输出.这意味着const限定符被删除,即f<int&>具有参数类型int&.
为什么会这样?据我了解,根据§14.3.1.4:
如果一个模板参数的模板参数
T名称的类型"参考CV1S",企图制造型"参考CV2T"创造型"参考CV12S",其中CV12是CV-合格网络ERS的联合CV1和cv2.冗余的cv-quali firs被忽略.
const不应该被丢弃.这是代码:
#include <iostream>
using namespace std;
template <typename T>
void f(const T& t)
{
t++;
}
int main()
{
int a = 1;
cout << a;
f<int&>(a);
cout << ' ' << a << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 考虑这个程序:
template<typename T>
struct Foo
{
void foo(const T&) {}
void foo(T&) {}
};
int main()
{
Foo<double&> f;
double d = 3.14;
f.foo(d); //complains that foo() is ambigous
}
Run Code Online (Sandbox Code Playgroud)
在上面,如果 Foo 被实例化为Foo<double>,那么一切都很好,但如果它被实例化为Foo<double&>,那么对 的调用就会foo变得不明确。在推导 的参数类型时 ref 是否会崩溃,foo如果是的话,为什么常量会被忽略?
我在玩 C++ 模板类型推导并设法编译了这个小程序。
template<typename T>
void f(const T& val)
{
val = 1;
}
int main()
{
int i = 0;
f<int&>(i);
}
Run Code Online (Sandbox Code Playgroud)
它可以在所有主要编译器上编译,但我不明白为什么。为什么可以f赋值val,什么时候val显式标记const?它是这些编译器中的错误还是根据 C++ 标准的有效行为?