使用SFINAE禁用模板类成员功能 [英] Using SFINAE to disable template class member function

查看:47
本文介绍了使用SFINAE禁用模板类成员功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使用SFINAE和 std :: enable_if 禁用模板类的单个成员函数?

Is it possible to use SFINAE and std::enable_if to disable a single member function of a template class?

我目前有一个与此相似的代码:

I currently have a code similar to this:

#include <type_traits>
#include <iostream>
#include <cassert>
#include <string>

class Base {
public:
    virtual int f() { return 0; }
};

template<typename T>
class Derived : public Base {
private:
    T getValue_() { return T(); }

public:
    int f() override {
        assert((std::is_same<T, int>::value));
        T val = getValue_();
        //return val; --> not possible if T not convertible to int
        return *reinterpret_cast<int*>(&val);
    }
};


template<typename T>
class MoreDerived : public Derived<T> {
public:
    int f() override { return 2; }
};


int main() {
    Derived<int> i;
    MoreDerived<std::string> f;
    std::cout << f.f() << " " << i.f() << std::endl;
}

理想地,如果 T!= int ,则应禁用 Derived< T> :: f().因为 f 是虚拟的,所以即使未调用任何 Derived 实例化,也会生成 Derived< T> :: f().但是使用了这样的代码,使得 Derived< T> (带有 T!= int )永远不会仅作为 MoreDerived< T> 的基类而创建.代码>.

Ideally, Derived<T>::f() should be disabled if T != int. Because f is virtual, Derived<T>::f() gets generated for any instantiation of Derived, even if it is never called. But the code is used such that Derived<T> (with T != int) never gets created only as a base class of MoreDerived<T>.

因此要使程序编译,必须使用 Derived< T> :: f()中的hack. reinterpret_cast 行永远不会执行.

So the hack in Derived<T>::f() is necessary to make the program compile; the reinterpret_cast line never gets executed.

推荐答案

您只需将 f 专门用于 int :

template<typename T>
class Derived : public Base {
private:
    T getValue_() { return T(); }

public:
    int f() override {
        return Base::f();
    }
};

template <>
int Derived<int>::f () {
    return getValue_();
}

这篇关于使用SFINAE禁用模板类成员功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆