想要使类方法具有与类模板参数匹配的签名,例如,对于一个类,如果 T 不为 void,则为 Class::Method(T t);如果 T 为 void,则为 Class::Method() .
编译下面尝试的代码,如果 T 为 void,则两种方法都存在。 我不明白为什么同样使用 enable_if 适用于 foo 但不适用于该版本的 print
#include <iostream>
using namespace std;
template <typename T>
struct S
{
template <typename U = T>
std::enable_if_t<std::is_void_v<U>, void>
print(void) { cout << "print void" << endl; }
template <typename U = T>
std::enable_if_t<not(std::is_void_v<U>), void>
print(U x) { cout << "print not void " << x << endl; }
template <typename U = T>
std::enable_if_t<not(std::is_void_v<U>), void>
foo() {};
// ... rest of class
};
int main()
{
S<int> i;
i.print(1);
// i.print(); // is disabled
S<void> v;
v.print();
v.print(2); // should be disabled but is not
v.foo(); // same enable_if use disabled this method
}
v.foo<int>()
您认为
foo
的 void 版本上的 S
版本不存在,这是错误的。 上面的代码将完美运行。
您所显示的是默认模板参数选择了一个不存在的版本。
在
print
的情况下,您提供默认模板参数 - 但您也允许它们显式传递(即 .print<double>(1)
)或推导(如 .print(2)
中)。
在这两种情况下,这都会导致
U
类型不是 T
,因此不是 void
。
至少有两种方法。 您可以阻止推导(让
foo
样式不存在以适用于 print
),甚至可以阻止传递显式参数(防止调用 foo<int>()
)。 其次,您还可以使用 requires
,它更干净,但需要较新版本的 C++。