我有一些处理函数地址、lambda和模板参数的代码。
下面是一个代码片段,它向我展示了这些函数地址的一些用法:
#include <type_traits>
int main() {
auto l = []{};
using L = decltype(l);
// fine, am I just lucky?
using type1 = std::integral_constant<decltype(&L::operator()), &L::operator()>;
struct Bar {
static void baz() {}
};
// error!
using type2 = std::integral_constant<decltype(&Bar::baz), &Bar::baz>;
}问题是,为了能够将&Bar::baz作为模板参数发送,它必须具有链接,因此出现错误。
为什么lambda案例有效?是因为它不是静态的,还是因为lambda的调用操作符有链接?
发布于 2017-08-23 11:42:41
lambda的闭包类型是一个未命名的类,请参阅[expr.prim.lambda.closure]/1。类的成员函数具有与其包含类的名称相同的链接(如果有);请参见[basic.link]/5。如果包含类没有名称(甚至不是为了链接目的),那么它的成员函数就没有链接。
此外,本地lambda的闭包类型是本地类,而本地类,即使是有名称的类,也没有链接;请参阅[expr.prim.lambda.closure]/2和[basic.link]/8。
在C++17之前,[temp.arg.nontype]/1.3中的链接要求适用于指针和引用,但不适用于指向成员的指针。根据这些规则,GCC正确地接受了您的lambda案件,驳回了您的Bar::baz案件。
N4268完全删除了C++17的链接要求,同时修改了模板非类型参数的规则。在C++17中,这两个示例都应该被接受。
https://stackoverflow.com/questions/45824686
复制相似问题