[英]Using SFINAE to disable template class member function
Is it possible to use SFINAE and std::enable_if
to disable a single member function of a template class? 是否可以使用SFINAE和std::enable_if
来禁用模板类的单个成员函数?
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;
}
Ideally, Derived<T>::f()
should be disabled if T != int
. 理想情况下,如果T != int
则应禁用Derived<T>::f()
。 Because f
is virtual, Derived<T>::f()
gets generated for any instantiation of Derived
, even if it is never called. 因为f
是虚拟的,所以Derived<T>::f()
会为Derived
任何实例化生成,即使它从未被调用过。 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>
(带有T != int
)永远不会仅作为MoreDerived<T>
的基类创建。
So the hack in Derived<T>::f()
is necessary to make the program compile; 所以Derived<T>::f()
的hack是编译程序所必需的; the reinterpret_cast
line never gets executed. reinterpret_cast
行永远不会被执行。
You could simply specialize f
for int
: 你可以简单地将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_();
}
No you can't rule out a member function with SFINAE. 不,你不能排除SFINAE的会员功能。 You could do it with specialisation of your Derived
class f
member function for convertible T
s to int
but that would lead to unnecessary duplication of code. 您可以通过特化Derived
类f
成员函数将可转换T
s转换为int
但这会导致不必要的代码重复。 In C++17 however you could solve this with use of if constexpr
: 但是在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();
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.