- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
看了 #1664( proposed resolution 1664 ) 的建议解决方案后,我对函数模板的默认参数的规则感到困惑,在此处引用内容:
根据 8.1.5 [expr.prim.lambda] 第 3 段
The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression. [Note: This determines the set of namespaces and classes associated with the closure type (6.4.2 [basic.lookup.argdep]). The parameter types of a lambda- declarator do not affect these associated namespaces and classes. —end note]
If a function template f is called in a way that requires a default argument to be used, the dependent names are looked up, the semantics constraints are checked, and the instantiation of any template used in the default argument is done as if the default argument had been an initializer used in a function template specialization with the same scope, the same template parameters and the same access as that of the function template f used at that point.
namespace J {
inline namespace K {
template <typename T> int zap(const T &t) { foo(t); return 0; }
template <typename T> void zip(int = zap([] { })) { }
}
template <typename T> void foo(const T &) { }
}
void bar() {
J::K::zip<long>();
/*Accroding to the above wording,the invoke just like:
=> J::K::zip<long>(zap([] { }));
*/
}
If zip were not a template, argument-dependent lookup successfully resolves the lookup for foo in all implementations tested; however, there is implementation variance in the handling of the example as written.
Change 17.8.1 [temp.inst] paragraph 13 as follows:
If a function template f is called in a way that requires a default argument to be used, the dependent names are looked up, the semantics constraints are checked, and the instantiation of any template used in the default argument is done as if the default argument had been an initializer used in a function template specialization with the same scope, the same template parameters and the same access as that of the function template f used at that point, except that the scope in which a closure type is declared (8.1.5 [expr.prim.lambda]) — and therefore its associated namespaces — remain as determined from the context of the definition for the default argument. This analysis is called default argument instantiation. The instantiated default argument is then used as the argument of f.
foo
无法通过
查找参数依赖查找 因为参数
[] { }
哪个命名空间既不是
J
也不是
K
,假设形式为
function bar
喜欢
J::K::zip<long>(zap([] { }) /*default argument*/);
,所以根据
[expr.prim.lambda] 第 3 段
[] { }
的命名空间在
fuction bar
在那个范围内,没有
foo
可以发现,所以强调的部分是针对这种考虑
[] { }
的命名空间的案例。内
zap
同
zap
,表示
[] { }
的命名空间是
K
,现在
foo
可以在父命名空间
J
中找到通过参数依赖查找规则,到目前为止,如果我误解了这些规则,请纠正我。另一种观点是每次调用函数时都会评估默认参数,即使默认值是
非依赖 .所以继续考虑下面的代码:
#include <iostream>
struct A {
};
template<typename T>
int func(T, float) { //#a
std::cout << "float" << std::endl;
return 0;
}
template<typename T>
void test(int = func(A{}, 0)) { //#1
}
template<typename T>
int func(T, int) { //#b
std::cout << "int" << std::endl;
return 0;
}
int main() {
test<A>(); //#2 transform to: test<A>(func(A{}, 0)); here,#b should be the best match
std::getchar();
}
func
是非依赖的,但是每次函数
test
时都要确定被调用,我在一些编译器中测试代码。
func
确定在
#1
和 MSVC 证明了
func
确定在
#2
.如果 MSVC 错误,这意味着可以在 #1 内确定非依赖的默认参数,不需要每次调用函数时都确定,为什么要添加强调部分?(
如果我正确理解强调部分,其目的是保持闭包类型的命名空间在默认参数中保持一致,无论 lambda 表达式是在函数声明点还是调用点 )。如果我误解了这些规则,如何正确解释它们?
最佳答案
默认参数是 评价 每次调用它们时,但这是一个运行时属性:调用不是按源代码行而是按实际控制流计数。另外,模板化函数的默认参数是 considered to be a definition并且是 实例化 需要时,每个 最多一次专业函数的(带有关于必须同意的多个实例化点的通常条件)。 CWG1664 是一个非常狭窄的问题,基于实例化的措辞:通过引入 虚构 函数模板,它留下了 lambda 声明“物理”移动的可能性。该修复确实只影响 ADL。
您的 func
示例反而说明了模板中通常的名称查找规则:无论多少次和从哪里test
的默认参数被实例化,func
在它不是受抚养人 name 并因此找到 func(T,float)
(每次)。 MSVC 众所周知,该规则从未正确实现(因为公平地说,他们的实现早于该规则,而且他们最近才开始对其模板支持进行必要的(并且几乎完全)重写)。
同时,最近的 GCC 在 CWG1664 示例中明显存在缺陷:请注意,它提示 foo
正在使用但未定义,矛盾 两者都清晰可见 { }
以及关于未找到它的先前错误消息。
关于c++ - 如何理解#1664的提议决议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60691059/
在 TypeScript 中,有方便的语法,constructor parameter properties : constructor(a, public b, private _c) {} 语法糖
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 7年前关闭。 Improve t
我是一名优秀的程序员,十分优秀!