热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

std::function,文字类型和模板

如何解决《std::function,文字类型和模板》经验,为你挑选了1个好方法。

我正在C ++ 17项目中,其中有以下定义(当然是在我的名称空间中):

using CppFunction = std::function;

template
using CppMethod = std::function;

现在,我声明一些功能:

template
constexpr CppFunction CppFunctionNative(F func);

template
constexpr CppMethod CppMethodNative(F func);

令我惊讶的是,第一个声明会导致编译器错误Constexpr function's return type is not a literal type,但是第二个效果很好。

为什么会这样?它与第二个函数的返回类型是template的事实有关吗?

UPD:简化的独立示例:

#include 

using CppFunction = std::function;

template
using CppMethod = std::function;

// Clang will complain
template
constexpr CppFunction CppFunctionNative(F func) {};

// Clang will not complain
template
constexpr CppMethod CppMethodNative(F func) {};

// main() function doesn't matter
int main() {
    CppFunctionNative(0);
    CppMethodNative(0);
    return 0;
};

有趣的是,OnlineGDB和离线GCC 8.3.0对此没有抱怨,但是我的Clang 8对此有所抱怨。



1> Yakk - Adam ..:

令我惊讶的是,第一个声明会导致编译器错误Constexpr函数的返回类型不是文字类型,但是第二个可以正常工作。

为什么会这样?它与第二个函数的返回类型是template的事实有关吗?

是。在第一种情况下,编译器可以证明的特定专业化std::function不是文字类型。

在第二种情况下,它必须T先知道的特定专长std::function是否为文字类型。

template
struct example {
  virtual T get() const {return {};}
  ~example() {}
};
template<>
struct example {};

#if 0
template
constexpr example test( F ) { return {}; }
#endif

template
constexpr example test2( F ) { return {}; }

现场例子

test是非法的;test2很好 其实test2( 3.14 )是合法的constexpr

现在,std::function没有这样的专业化,但这不是编译器需要证明的。这样做通常需要解决暂停问题,这是C ++标准试图避免要求编译器这样做的问题。

如@MaxLanghof所提到的,这种错误导致“格式错误,无需诊断”程序。不会强制编译器检测到您的constexpr函数不能为constexpr,但是如果您这样做,则编译器可以自由执行任何操作,包括生成错误消息(或更糟糕的事情)。

因此,GCC忽略错误并没有错,而clang发出错误也没有错。从某种意义上说,Clang的错误发出要比gcc的省略要高。


推荐阅读
author-avatar
厦禾Tony_303
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有