c++ - 函数重载时的 SFINAE 和隐式强制转换
问题描述
我正在尝试编写一个模板助手,让我检查一组类型是否与结构成员的类型匹配。到目前为止,我已经写了这个——
#include <iostream>
#include <functional>
struct foo {
int field1;
int field2;
};
template <typename...T, std::size_t ...indices >
constexpr bool construct (std::index_sequence<indices...>) {
foo s = {std::get<indices>(std::tuple<T...>())...};
return true;
}
template<typename...T>
static bool allowed(int) {
construct<T...>(std::index_sequence_for<T...>());
return true;
}
template<typename...T>
static bool allowed(long) {
return false;
}
int main() {
std::cout << allowed<int, int, int>(0);
return 0;
}
在这里,显然调用allowed<int, int, int>
是无效的,因为构造不能被调用(foo 有 2 个成员并且它被初始化为 3)。但是还有另一种 allowed 的实现,它以long
参数为参数。由于 SFINAE,编译器不应该简单地匹配 allowed 和 return 的第二个模板实现false
吗?但它反而给了我一个错误-
错误:'foo' 的初始化程序太多</p>
foo s = {std::get<indices>(std::tuple<T...>())...};
如果我只是注释掉 allowed 的第一个实现,那么一切都很好,我得到一个错误的结果。我对模板替换如何与隐式强制转换和函数重载交互感到困惑。如果不允许这样做,有没有办法可以达到相同的效果?
解决方案
foo
不在直接上下文中,因此您会遇到硬错误而不是 SFINAE。考虑一下:
#include <iostream>
#include <functional>
struct foo {
int field1;
int field2;
};
template <typename U, typename...T, std::size_t ...indices >
constexpr auto construct (std::index_sequence<indices...>) -> decltype(new U {std::get<indices>(std::tuple<T...>())...}) {
return nullptr;
}
template<typename...T, typename Q = decltype(construct<foo, T...>(std::index_sequence_for<T...>()))>
static bool allowed(int) {
return true;
}
template<typename...T>
static bool allowed(long) {
return false;
}
int main() {
std::cout << "allowed<int,int>(0) = " << allowed<int,int>(0) << std::endl;
std::cout << "allowed<int,int,int>(0) = " << allowed<int,int,int>(0) << std::endl;
return 0;
}
推荐阅读
- ruby-on-rails - Heroku 部署失败:错误:安装节点的“12.x”时出现未知错误
- flutter - 如何用这条曲线制作背景?
- excel - 将一行与另一行进行比较以弹出重复消息,如果仍然存在重复则限制移动到下一行
- ruby-on-rails - Rails 6 ActionController::Base.new.render_to_string
- electron - 如何在 linux 和 window 64bit 中使用 Agora Electron SDK?
- ironpython - 在 IronPython 中,如何获取选中的单选按钮并将按下的按钮等同于文本变量?
- file - Rust:如何从文件中读取十六进制
- python - 转换 keras 模型时,Kaggle GPU 不起作用
- java - 将二进制格式保存到整数列表的问题
- php - 为什么递归静态函数的行为不像预期的那样?