模板参数推导由于恒定性不一致而失败
Template argument deduction failure due to inconsistent constness
考虑以下内容(它不能编译,但我们稍后会修复它(:
void foo(const int *n) { }
template <typename ...Args>
void bar(void (*func)(Args...), Args... args) { func(args...); }
int main(int argc, char *argv[])
{
int n = 42;
bar(foo, &n);
}
模板函数bar()
接受要调用的函数指针和要传递给它的参数的参数包。 GCC 7.4.0 诊断以下错误:
test.cpp:6:6: note: template argument deduction/substitution failed:
test.cpp:11:16: note: inconsistent parameter pack deduction with ‘const int*’ and ‘int*’
很明显,类型推导规则还不够宽松,不允许在同时遵守const T*
和T*
的情况下推导出const T*
。好的,好的。这很容易用石膏修复:
bar(foo, static_cast<const int *>(&n));
但这很丑陋。C++17 有std::as_const()
,这使得它不那么丑陋(&std::as_const(n)
(,但在我目前的项目中,我仅限于 C++14,悲伤的脸。
问:有没有办法重新排列此代码,以便在不显式指定bar()
模板参数和不强制转换以解决不明确的恒常性的情况下成功进行类型推断?允许跳出框框思考,只要我可以将函数指针及其参数传递给模板函数!
您可以将函数指针的推导和参数分开:
void foo(const int *n) {}
template <typename... FArgs, typename... Args>
void bar(void (*func)(FArgs...), Args&&... args) {
func(std::forward<Args>(args)...);
}
int main(int argc, char *argv[]) {
int n = 42;
bar(foo, &n);
}
但是在这一点上,我想知道为什么函数指针需要分解。为什么不接受任何可赎回的?
void foo(const int *n) {}
template <typename F, typename... Args>
void bar(F func, Args&&... args) {
func(std::forward<Args>(args)...);
}
int main(int argc, char *argv[]) {
int n = 42;
bar(foo, static_cast<const int *>(&n));
bar([](int const*){}, &n);
}
另外,请记住,C++17 优惠std::invoke
:
std::invoke(foo, &n);
相关文章:
- 大于65535的C++数组[size]引发不一致的溢出
- 在 C++(和 C)中进行类型转换时明显不一致
- 填充上编译器生成的复制构造函数之间的不一致
- 犰狳的 print() 方法和 cout 在从 Rcpp 调用时顺序不一致
- CreateDIBSection为同一图像返回不一致的位图位值
- 在 Qml 中从 QSqlTableModel 中删除单行时视图不一致
- 模板参数推导不一致
- 指针类型类成员的动态强制转换的恒定性是什么?
- 声明中不一致的no是否违反ODR?
- 如何删除分支因子不一致的树,最大为 30,40
- 从 C++ 函数与 Python 函数返回的不一致值用于偏斜正态分布
- 从 C 字符串构造 std::string 与从另一个 std::string 构造 std::string 不一致
- 为什么对引用的常量引用会失去其恒定性?
- 这种比较是否不一致(或者存在其他问题)?
- 以下可变参数模板行为是否不一致?
- 如何修复我的链表读数不一致的问题?
- 在C++17中,为什么类模板和函数模板的指针类型推导明显不一致
- void 函数中的指针参数返回不一致的值
- 模板参数推导由于恒定性不一致而失败
- 为什么普遍引用不保持其论点的恒定性