为什么在推导模板参数时应用 §5/5?规则不能不同吗?
Why is §5/5 applied when deducing template arguments? Couldn't the rules be different?
考虑以下示例:
#include <iostream>
template<typename T>
void f(T t) {
std::cout << t << 'n';
static_assert(std::is_same<T, int const*>::value, "T != int const*");
static_assert(std::is_same<decltype(t), int const*>::value, "decltype(t) != int const*");
}
template<typename T>
void g(T t) {
std::cout << t << 'n';
static_assert(std::is_same<T, int>::value, "T != int");
static_assert(std::is_same<decltype(t), int>::value, "decltype(t) != int");
t++;
}
int main()
{
int x = 22;
int const* px = &x;
f(px);
int const& rx = x;
g(rx);
}
代码正常执行。但是根据当前的规则,我们得到:
-
T == int const*
和t
在调用f(px)
的模板函数f
实例化中具有int const*
类型。 -
T == int
和t
在调用g(rx)
的模板函数g
的实例化中具有int
类型。
对于第二个演绎,我首先想到的是与指针情况对称的东西,即T == int const&
和t
具有int const&
类型。
我想我知道编译器执行的当前演绎过程是怎么回事。在§5.5中,引用在传递给g
的表达式rx
中被删除。也就是说,用于参数演绎的rx
的类型是int const
。注意,通过此更改,在rx
声明中为而不是顶级的const
变成了顶级const
。然后根据§14.8.2.1/2,第三点,const
在int const
类型中被忽略,因为它现在是顶级的const
。
关于基本原理,让我们首先考虑为什么const
没有进入参数类型演绎:
template< class Type >
void foo( Type v ) { v = 0; }
auto main() -> int
{
int const x = 3;
foo( x );
}
这在机制上编译得很好,因为c++ 11§14.8.2.1/2第三个破折号是这样说的,“ A
类型的顶级cv-限定符被忽略用于类型推导”。
我猜其中很大一部分原因是,否则各种实际参数cv-限定将产生与函数类型完全相同的函数模板实例化,因为形式参数的顶级cv-限定被忽略了。到函数的类型。这样的实例化可以产生非常不同的效果。那会很乱的。
然后,关于为什么删除引用,如果不是,那么这个程序,
#if defined( USE_REF )
# define Q &&
auto kind = "ref";
#else
# define Q
auto kind = "non-ref";
#endif
template< class A1, class A2 >
void foo( A1 a1, A2 a2 )
{
a1 ^= a2;
a2 ^= a1;
a1 ^= a2;
}
#include <iostream>
#include <typeinfo>
auto main() -> int
{
using namespace std;
int Q a1 = 111;
int Q a2 = 222;
foo( a1, a2 );
cout << kind << ' ' << a1 << ' ' << a2 << endl;
}
将根据USE_REF
输出不同顺序的数字。
但事实并非如此。
这是因为引用的设计使得在c++ 03中,a1
是int
的引用,与直接是int
的a1
是无法区分的。
对于基本原理的更明确和更有见地的观点(上面的观点非常合理,但仍然只是我的想法),可能是Bjarne stroustrup的《c++的设计和演变》。书里有些东西。与否。可惜我没有那本书。
相关文章:
- 此代码是否违反一个定义规则
- 生成文件不对文件使用隐式规则
- 变量可能尚未初始化[MIRA 2012规则9.1,强制性]
- 静态结构和一个定义规则
- 尽管遵循了规则,内存泄漏在哪里
- 这是关于成员访问规则的正确摘要吗
- uint_not_usable_without_attribute在业力规则中使用数字生成器时静态断言失败
- 增强精神解析器规则以检测语句中的特殊结尾
- 制作文件:没有规则来制定目标:如何设置正确的规则?
- 为什么此指针值不能转换为整数的规则是什么?
- 传递通用函数,用于梯形规则的数值积分
- C++内存模型中的确切规则阻止在获取操作之前重新排序
- 模板如何影响C++中隐式声明的规则?
- antlr 规则上下文是否可以独立于目标
- Bison/flex 在识别规则后等待输入
- 生成文件中隐式规则中的 -c 标志出错
- 单链接列表实现,规则为 3
- 指针算术规则中的"possibly-hypothetical"是什么意思?
- 假设声明中某些上下文中需要的名称查找规则是什么
- 为什么在推导模板参数时应用 §5/5?规则不能不同吗?