为什么此模板参数推理失败
why fails this template parameter inference?
我试图理解为什么这个片段失败:
#include <iostream>
using namespace std;
template <typename Lambda>
struct Handler
{
bool _isCompleted;
bool isCompleted() { return _isCompleted; }
Lambda _l;
Handler(Lambda&& l) : _l(l) {}
void call() { _l(this); }
};
int main()
{
auto l1 = new Handler( [&](decltype(l1) obj )->
{
obj->_isCompleted = true;
cout << " is completed?" << obj->isCompleted() << endl;
});
l1->call();
};
G++ 4.5 失败并显示:
test.cpp: In function ‘int main()’:
test.cpp:21:17: error: expected type-specifier before ‘Handler’
test.cpp:21:17: error: expected ‘,’ or ‘;’ before ‘Handler’
test.cpp:25:2: error: expected primary-expression before ‘)’ token
test.cpp:25:2: error: expected ‘;’ before ‘)’ token
test.cpp:26:7: error: request for member ‘call’ in ‘* l1’, which is of non-class type ‘int’
我的理解是auto l1
应该解析为Handler<lambdaType>*
,而lambdaType应该有一个公共函数签名void( Handler<LambdaType>*)
。我认为上面的例子没有任何明显的错误(你知道,除了 lambda 和处理程序类型之间的丑陋和略带病态的循环依赖关系(
一个问题是,正如@Cat所说,模板参数推导不适用于构造函数调用。始终需要指定模板参数。
另一个问题由Clang用以下片段很好地说明:
struct X{
X(...){}
};
int main(){
auto l = X([](decltype(l)& o){});
}
输出:
t.cpp:6:26: error: variable 'l' declared with 'auto' type cannot appear in its
own initializer
auto l = X([](decltype(l)& o){});
^
1 error generated.
强制性标准报价:
§7.1.6.4 [dcl.spec.auto] p3
否则,变量的类型是从其初始值设定项推导的。要声明的变量的名称不应出现在初始值设定项表达式中。[...]
类型推导不适用于构造函数。 auto
将推断表达式的类型,是的,但new Handler()
需要显式类型。改为编写工厂函数:
// also don't use raw owning pointers
template <typename L>
std::unique_ptr<Handler<L>> make_handler(L lambda) {
return std::unique_ptr<Handler<L>>(new Handler<L>(lambda));
}
当然,它重复了一下,但只有一次。然后你可以做
auto l1 = make_handler([](...) { ... });
auto l2 = make_handler([](...) { ... });
它会正常工作。
相关文章:
- 如果没有malloc,链表实现将失败
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 视图中的参数推导失败:take_while
- 链接到自行创建的dll失败
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- GetShortPathName在网络驱动器上使用中文文件夹时失败
- gcc和c++17的过载解析失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在WSL:configure_file上对config_file的每次调用都失败:配置文件时出现问题
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- 从父数组测试用例构造二叉树失败
- LibGit2 SSH身份验证失败
- 如何让LLDB在成功时退出,在失败时等待
- VS2017,C++包含目录与附加包含目录,子文件夹包含失败-但为什么
- 为什么此模板参数推理失败
- 矩阵积的 Cholesky 的特征和 C++11 类型推理失败
- 为什么此模板推理失败