我有一个模板类 C<T>
我打算用 T
实例化它和其他一些类(class)一样A
和 B
. C<T>
有一个方法 foo
我要看谁的签名T
被实例化为 A
或 B
.例如,考虑以下代码:
#include <iostream>
#include <string>
class A {
public:
void message() {
std::cout << "message with no args" << std::endl;
}
};
class B {
public:
void message(int x) {
std::cout << "message with " << x << std::endl;
}
};
template<typename T>
class C {
private:
T internal;
public:
C(T& x) {
internal = x;
}
void call() {
internal.message();
}
void call(int x) {
internal.message(x);
}
};
int main(int argc, char* argv[]) {
A a;
B b;
C<A> ca(a);
C<B> cb(b);
ca.call();
cb.call(42);
// ca.call(42); ERROR HERE
return 0;
}
这运行正确。 ca.call(42)
会引发编译错误,因为没有方法 A::message(int)
.但是,如果我出于某种原因引入一种方法 A::message(int)
在A
,代码可能允许调用 ca.call(42)
,我想阻止。
我知道 SFINAE 技术允许声明一个方法 C::call(T::call_type x)
其中 T::call_type
将是 T
的每个预期实例化的 typedef .但是,这只允许我更改 C::call
的参数类型.相反,我想制作 C::call
的签名(特别是参数数量)在 T
.因此我会阻止 ca.call(42)
即使有方法 A::message(int)
也不能成为有效调用在A
.
有什么办法吗?
最佳答案
我不知道 SFINAE 的所有来龙去脉,但你怎么看这个?
template <
typename = std::enable_if_t<std::is_same<std::decay_t<T>, A>::value>>
void call() {
internal.message();
}
template <
typename = std::enable_if_t<std::is_same<std::decay_t<T>, B>::value>>
void call(int x) {
internal.message(x);
}
你也可以使用== false
template <
typename = std::enable_if_t<std::is_same<std::decay_t<T>, B>::value == false>>
关于c++ - SFINAE 和参数数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47858811/