是否可以使用SFINAE并std::enable_if禁用模板类的单个成员函数?
我目前有一个类似于此的代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,Derived<T>::f()如果是,应该禁用T != int.因为f是虚拟Derived<T>::f()的Derived,所以即使从未调用过,也会为任何实例化生成.但是使用的代码使得Derived<T>(with T != int)永远不会仅作为基类创建MoreDerived<T>.
所以hack in Derived<T>::f()是编译程序所必需的; 该reinterpret_cast行永远不会被执行.
你可以简单地专注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_();
}
Run Code Online (Sandbox Code Playgroud)
不,你不能排除SFINAE的会员功能.您可以通过将可转换s的Derived类f成员函数专门化T来实现,int但这会导致不必要的代码重复.在C++ 17中,您可以使用以下方法解决此问题if constexpr:
template<typename T> class Derived : public Base {
T getValue_() { return T(); }
public:
int f() override {
if constexpr(std::is_convertible<T, int>::value) return getValue_();
return Base::f();
}
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
620 次 |
| 最近记录: |