c++ - SFINAE 和参数数量

标签 c++ templates sfinae

我有一个模板类 C<T>我打算用 T 实例化它和其他一些类(class)一样AB . C<T>有一个方法 foo我要看谁的签名T被实例化为 AB .例如,考虑以下代码:

#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/

相关文章:

C++ 多映射迭代器失效

c++ - 在 Makefile 的什么地方放东西(CFLAGS 或 CXXFLAGS)?

c++ - friend 模板运算符<<无法访问类的保护成员

c++ - 嵌套模板与移位运算符

c++ - 如果 std::vector 作为 T::Zero 存在,如何生成代码以使用自定义零值初始化 std::vector?

c++ - 应用具有通用引用的 SFINAE 模式

c++ - 使用 SFINAE 检测某物是否在( boost )范围内

c++ - Kerberos 管理员授权

c++ - std::vector 或 boost::vector 线程安全吗?

c++ - 参数列表中的 void_t 有效但不作为返回类型