使用 SFINAE 有选择地实例化模板的成员函数
Selectively instantiate member functions of a template with SFINAE
所以在模板 class 中,我试图根据一些静态提供的信息来实例化不同的成员。在下面的模板中,如果满足某些条件,则 selectiveMember
包含在 SelectiveClass
中,否则,模板将在没有 selectiveMember
的情况下实例化,但仍包含 foo
.
template<typename T>
struct SelectiveClass{
void foo(){...}
template<condition_check<T>::type=0>
void selectiveMember{...}
}
但是,如果不满足条件,这种实现将丢弃整个 class。尽管如此,使用CRTP技术,我们还是可以达到目的的。
template<typename T>
struct SelectiveClass: Specialize<T>{
void foo(){...}
}
template<typename T>
struct Specialize{
template<condition_check<T>::type=0>
void selectiveMember{...}
}
但是使用这种技术,每个选择性成员都需要另一个专门的继承。
所以我的问题是:有没有更优雅的方式允许这种选择性成员模板?
您的 enable_if
无法按您希望的方式工作的原因是因为它没有在直接上下文中使用(例如,参见 here)。但是,如果在 selectiveMember
函数中插入默认模板参数,则可以实现所需的效果。在下面的示例中,我使用了 condition
的具体示例,但您可以将其替换为您自己的示例。
#include <type_traits>
template<typename T>
struct SelectiveClass{
void foo(){}
template <class X = T, std::enable_if_t<std::is_integral<T>::value, X>* = nullptr>
void selectiveMember(){}
};
using test_int = SelectiveClass<int>;
using test_double = SelectiveClass<double>;
int main() {
test_int x;
test_double y;
x.selectiveMember();
// y.selectiveMember(); fails to compile as expected
}
所以在模板 class 中,我试图根据一些静态提供的信息来实例化不同的成员。在下面的模板中,如果满足某些条件,则 selectiveMember
包含在 SelectiveClass
中,否则,模板将在没有 selectiveMember
的情况下实例化,但仍包含 foo
.
template<typename T>
struct SelectiveClass{
void foo(){...}
template<condition_check<T>::type=0>
void selectiveMember{...}
}
但是,如果不满足条件,这种实现将丢弃整个 class。尽管如此,使用CRTP技术,我们还是可以达到目的的。
template<typename T>
struct SelectiveClass: Specialize<T>{
void foo(){...}
}
template<typename T>
struct Specialize{
template<condition_check<T>::type=0>
void selectiveMember{...}
}
但是使用这种技术,每个选择性成员都需要另一个专门的继承。
所以我的问题是:有没有更优雅的方式允许这种选择性成员模板?
您的 enable_if
无法按您希望的方式工作的原因是因为它没有在直接上下文中使用(例如,参见 here)。但是,如果在 selectiveMember
函数中插入默认模板参数,则可以实现所需的效果。在下面的示例中,我使用了 condition
的具体示例,但您可以将其替换为您自己的示例。
#include <type_traits>
template<typename T>
struct SelectiveClass{
void foo(){}
template <class X = T, std::enable_if_t<std::is_integral<T>::value, X>* = nullptr>
void selectiveMember(){}
};
using test_int = SelectiveClass<int>;
using test_double = SelectiveClass<double>;
int main() {
test_int x;
test_double y;
x.selectiveMember();
// y.selectiveMember(); fails to compile as expected
}