【发布时间】:2022-11-26 05:36:34
【问题描述】:
我了解了 SFINAE 原理及其各种用途。然后我写了下面的程序,用 gcc 编译但不用 msvc 和 clang。 Live demo。
#include <iostream>
#include <type_traits>
template <typename T> class Container {
public:
template<typename U = T>
std::enable_if_t<std::is_same_v<T, int>> foo(const T&)
{
}
};
template<typename T>
void func(T&& callable)
{
Container<int> c;
(c.*callable)(4);
}
int main(){
//works with gcc but not with clang and msvc
func(&Container<int>::foo);
}
正如我们所看到的,上面的程序适用于 gcc,但不适用于 clang 和 msvc,我不知道哪个编译器就在这里。那么这个程序是良构的还是病态的等等。
【问题讨论】:
-
问题不在于
enable_if。将其更改为void,您应该会得到相同的错误。 -
凉爽的。如果在指向
foo的指针处显式特化foo<int>,则工作正常。此外,它要么在不使用时自动“跳过”成员函数,因此您不需要禁用它们,要么有多个这样的函数,并且每次“获取指针”时都禁用除一个之外的所有函数,但是那么在获取指向它的指针时,您仍然需要以某种方式消除您对哪个函数感兴趣的歧义。你有用例吗? -
由于CWG 2608,该程序格式正确。
-
顺便说一句,你的
enable_if用法是错误的:实例化Container<char>会产生硬错误,你需要std::enable_if_t<std::is_same_v<U, int>>。在 C++20 中,requires(std::is_same_v<T, int>)(并删除模板)会简化事情。
标签: c++ language-lawyer