c++ - 在非依赖名称场景中对模板基类进行名称查找
问题描述
以下面的代码为例:
template <typename T>
struct foo_base
{
void doit(T*) {}
};
template <typename T>
struct foo : foo_base<T> {};
template <typename T>
struct get_result
{
template <typename Result>
static Result GetType(void (T::*)(Result*));
using type = decltype(GetType(&T::doit));
};
int main()
{
std::cout << typeid(typename get_result<foo<int>>::type).name() << '\n';
}
此代码无法同时使用 GCC 和 Clang 编译,但使用 MSVC 编译成功。clang给出的错误是:
<source>:21:27: error: use of undeclared identifier 'GetType'
using type = decltype(GetType(&T::doit));
^
<source>:26:34: note: in instantiation of template class 'get_result<foo<int> >' requested here
std::cout << typeid(typename get_result<foo<int>>::type).name() << '\n';
^
<source>:19:19: note: must qualify identifier to find this declaration in dependent base class
static Result GetType(void (T::*)(Result*));
^
通常,在一致性方面,我会支持 GCC/Clang,尤其是当它们都同意时,但我无法准确解释原因。当get_result<foo<int>>
被实例化时,它也应该实例化foo_base<int>
,所以我认为表达式T::doit
应该编译没有问题。
FWIW 的解决方法相当简单:
template <typename Type, typename Result>
static Result GetType(void (Type::*)(Result*));
解决方案
&foo<int>::doit
实际上是&foo_base<int>::doit
所以它的类型是void (foo_base<int>::*)(int*)
,但GetType
期望参数类型void (foo<int>::*)(T*)
,所以不能推断T
。
推荐阅读
- php - 上传的 UTF-8 编码的 csv 文件在获取内容后有三角形问号字母(捷克字母)
- javascript - 在浏览器中不显示图像的反应标记
- python-3.x - (初学者/Python)从列表中追加或删除条目,然后打印到 TextTable
- android - MP4 无法在 Android 视频播放器中正常播放,但可与 VLC、QuickTime 和 Chrome 浏览器一起使用
- php - 如何在 Laravel 8 中使用 Ajax
- flutter - `手势检测器`不起作用,它不会产生任何错误
- dolphindb - 更新时新值的数据类型与列因子的数据类型不匹配
- reactjs - 提交后如何调用渲染
- python - 在 django 中,我如何遍历父模型(用户)中的特定字段,包括附加子模型(用户配置文件)中的一些特定字段
- angular - Angular - 接收@Input时,如何在执行@Input逻辑之前等待子组件中的其他异步数据