如何有条件地实例化具有多个模板参数的模板 class?
How to conditionally instantiate a template class which has more than one template parameter?
我已经关注了这个post:Class template SFINAE
实例化模板 class 有条件地.
这对于只有一个模板参数的 classes 非常有效,如上面的 link 所示。
但是,我有两个(模板)参数,我想做一些 SFINE 检查。
以下是我的代码的一个最小示例。
#include <type_traits>
#include <string>
template<class T, class U, class R> using arithmetic_types = std::enable_if_t<
std::is_arithmetic_v<T> &&
std::is_arithmetic_v<U>,
R
>;
template<class T, class U, class Enable = void> class MyClass;
template<class T, class U, arithmetic_types<T, U, void>>
class MyClass {
public:
MyClass() = default;
};
int main()
{
MyClass<int, int> o; // should work
MyClass<int, double> o1; // should work
MyClass<int, std::string> o2; // should be a complier error
return 0;
}
上面给了我错误信息:https://godbolt.org/z/BEWJMp
error C3855: 'MyClass': template parameter 'Enable' is incompatible with the declaration
error C2079: 'o' uses undefined class 'MyClass'
error C2079: 'o1' uses undefined class 'MyClass'
error C2079: 'o2' uses undefined class 'MyClass'
很遗憾,我无法理解错误消息(error C3855:
)。
为什么我不能对更多的模板参数做上面link的相同原理?
对此最好的解决方案是什么?
问题出在 MyClass 的模板特化中。特化应该只在 类 T
和 U
这两个参数上进行参数化,测试应该放在声明中,如下例所示。
#include <string>
#include <type_traits>
template <class T, class U, class R>
using arithmetic_types = std::enable_if_t<
std::is_arithmetic_v<T> && std::is_arithmetic_v<U>, R>;
template <class T, class U, class Enable = void>
class MyClass;
template <class T, class U> //<- Remove the test from here
class MyClass<T, U, arithmetic_types<T, U, void>> //<- Put the test here.
{
public:
MyClass() = default;
};
int main()
{
MyClass<int, int> o; // should work
MyClass<int, double> o1; // should work
MyClass<int, std::string> o2; // should be a complier error
return 0;
}
我已经关注了这个post:Class template SFINAE 实例化模板 class 有条件地.
这对于只有一个模板参数的 classes 非常有效,如上面的 link 所示。
但是,我有两个(模板)参数,我想做一些 SFINE 检查。 以下是我的代码的一个最小示例。
#include <type_traits>
#include <string>
template<class T, class U, class R> using arithmetic_types = std::enable_if_t<
std::is_arithmetic_v<T> &&
std::is_arithmetic_v<U>,
R
>;
template<class T, class U, class Enable = void> class MyClass;
template<class T, class U, arithmetic_types<T, U, void>>
class MyClass {
public:
MyClass() = default;
};
int main()
{
MyClass<int, int> o; // should work
MyClass<int, double> o1; // should work
MyClass<int, std::string> o2; // should be a complier error
return 0;
}
上面给了我错误信息:https://godbolt.org/z/BEWJMp
error C3855: 'MyClass': template parameter 'Enable' is incompatible with the declaration
error C2079: 'o' uses undefined class 'MyClass'
error C2079: 'o1' uses undefined class 'MyClass'
error C2079: 'o2' uses undefined class 'MyClass'
很遗憾,我无法理解错误消息(error C3855:
)。
为什么我不能对更多的模板参数做上面link的相同原理?
对此最好的解决方案是什么?
问题出在 MyClass 的模板特化中。特化应该只在 类 T
和 U
这两个参数上进行参数化,测试应该放在声明中,如下例所示。
#include <string>
#include <type_traits>
template <class T, class U, class R>
using arithmetic_types = std::enable_if_t<
std::is_arithmetic_v<T> && std::is_arithmetic_v<U>, R>;
template <class T, class U, class Enable = void>
class MyClass;
template <class T, class U> //<- Remove the test from here
class MyClass<T, U, arithmetic_types<T, U, void>> //<- Put the test here.
{
public:
MyClass() = default;
};
int main()
{
MyClass<int, int> o; // should work
MyClass<int, double> o1; // should work
MyClass<int, std::string> o2; // should be a complier error
return 0;
}