首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果模板参数显式指定为函数类型怎么办?

如果模板参数显式指定为函数类型怎么办?
EN

Stack Overflow用户
提问于 2022-10-15 18:44:16
回答 1查看 62关注 0票数 -1

我尝试了下面的代码(https://godbolt.org/z/rcfPK451M)

代码语言:javascript
复制
bool cmp1(int &a, int &b) { return a < b; }

template<typename T> struct S;
template<typename T> void test(T cmp) { 
    S<T> t;
    S<decltype(cmp)> s; 
}

void foo() {
    test<decltype(cmp1)>(cmp1);
}

并得到以下编译错误:

代码语言:javascript
复制
<source>:5:10: error: 'S<bool(int&, int&)> t' has incomplete type
    5 |     S<T> t;
      |          ^
<source>:6:22: error: 'S<bool (*)(int&, int&)> s' has incomplete type
    6 |     S<decltype(cmp)> s;
      |                      ^

这表明Tbool(int&, int&)类型,cmpbool (*)(int&, int&)类型。

我搞不懂他们为什么有不同的类型。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-15 18:49:32

您正在使用该函数类型(参数cmp)声明一个变量,因此该类型退化为函数指针类型。您不能拥有具有函数类型的变量,而只能具有指向函数的指针。

标准说tem.扣减/3:

在执行此替换后,8.3.5中描述的函数参数类型调整是按格式进行的.[示例:“void ()(const,int5)”参数类型变为“void()( int,int)”。-最终例子]

简而言之,这种衰减是因为变量是函数模板的参数,并且在类型推断之后发生。如果您尝试decltype(cmp1) a = cmp1;,则不会发生这种情况,因为decltype(cmp1) a实际上声明了一个函数,因此不需要发生衰变(然后您就不能将其分配给一个函数)。

test中,T仍然是函数类型,因为您使用decltype(cmp1)显式地指定了它。删除它,让模板参数的演绎发生,你可以看到它被推导成腐朽的类型(因为这是参数cmp的实际类型)。

这与使用std::decay (对于函数类型等效于std::add_pointer )是一样的:

代码语言:javascript
复制
S<std::decay_t<T>> t;

演示

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74082118

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档