c++ - 为什么 SFINAE 在这个简单的成员函数重载中不起作用
问题描述
为什么 SFINAE 在这个简单的例子中不起作用?如果我注释掉模板化的“添加”,则代码编译正常。为什么编译器在替换失败后不尝试调用非模板'add'?
我正在使用 MSVS 2017。
#include <set>
#include <memory>
struct button_t
{
virtual ~button_t() {}
};
struct up_down_button_t : button_t
{
};
struct gui_t
{
std::set<std::shared_ptr<button_t> > buttons;
void add(const std::shared_ptr<button_t>& b) {
buttons.insert(b);
}
template<class container_t>
void add(container_t& c) {
for (auto& i : c)
add(i);
}
} gui;
int main(int argc, char* argv[]) {
auto b = std::make_shared<up_down_button_t>();
gui.add(b);
}
是否可以在没有冗长的样板代码(例如 std::enable_if 等)的情况下使该代码工作?
解决方案
只有函数类型或其模板参数类型 [或其显式说明符 (C++20 起)] 的直接上下文中的类型和表达式中的失败是 SFINAE 错误
在这里,失败发生在函数体中,所以它是替换失败,但不是在 SFINAE 上下文中 - 所以这是一个错误。
概念旨在帮助减少样板文件的繁重,因此如果您的编译器已经支持它们,您可以尝试使用它们。
推荐阅读
- swift - iPhone连接MaOS时检测USB
- c# - 如何在等待来自 ContentDialog 的用户输入时进行处理
- java - 如何在使用 testng 和 cucumber 时将屏幕截图附加到主思想报告?
- html - 在 Perl 中编码特殊字符
- android - Android cordova-plugin-media MediaError.MEDIA_ERR_ABORTED = 1 与 http 资源
- javascript - 我该怎么办:每次输入值更改时自动按“Enter”。(JS)
- javascript - 如何读取/传递 Vercel 系统环境变量以在 Sanity 中编码?
- pthreads - 如何获取现有互斥锁的属性?(pthread 库)
- python - 映射在单独文件中定义的 sql alchemy 数据库模型
- visual-studio-2019 - 如何从 Visual Studio 2019 的发布文件夹中排除某些文件或文件夹?