有些事情对我来说不是很好。这是声明一个只接受浮点模板参数的类的方式吗?
template <typename T, swift::enable_if<std::is_floating_point<T>::value> = nullptr>
class my_float;
我无法在这个类之外定义方法。不能编译,不确定原因
发布于 2017-12-31 20:54:16
好吧..。不完全是SFINAE。但是也许,使用模板专门化?如下所示?
template <typename T, bool = std::is_floating_point<T>::value>
class my_float;
template <typename T>
class my_float<T, true>
{
// ...
};
如果你真的想使用SFINAE,你可以写
template <typename T,
typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
class my_float
{
// ...
};
或者(观察你的例子中没有的指针)
template <typename T,
typename std::enable_if<std::is_floating_point<T>::value>::type * = nullptr>
class my_float // ------------------------------------------------^
{
};
编辑-- --
正如Yakk所建议的(谢谢!),您可以混合SFINAE和模板专门化来为不同的类型组开发不同版本的类。
例如,下面的my_class
template <typename T, typename = void>
class my_class;
template <typename T>
class my_class<T,
typename std::enable_if<std::is_floating_point<T>::value>::type>
{
// ...
};
template <typename T>
class my_class<T,
typename std::enable_if<std::is_integral<T>::value>::type>
{
// ...
};
开发了两个版本(两个不同的部分专门化),第一个版本用于浮点类型,第二个版本用于整数类型。并且可以容易地扩展。
发布于 2018-01-08 19:36:01
您还可以使用static_assert
毒化无效类型。
template <typename T>
class my_float {
static_assert(std::is_floating_point<T>::value,
"T is not a floating point type");
// . . .
};
在我看来,这更直接一点。
使用其他任何一种方法,例如
template <typename T, bool = std::is_floating_point<T>::value>
class my_float;
template <typename T> class my_float<T, true> { /* . . . */ };
my_float<int,true>
是有效类型。我并不是说这是一种糟糕的方法,但是如果您想要避免这种情况,就必须将my_float<typename,bool>
封装在另一个模板中,以避免暴露bool
模板参数。
发布于 2021-02-15 20:06:00
事实上,这样的东西对我来说是有效的(感谢SU3的回答)。
template<typename T, bool B = false>
struct enable_if {};
template<typename T>
struct enable_if<T, true> {
static const bool value = true;
};
template<typename T, bool b = enable_if<T,is_allowed<T>::value>::value >
class Timer{ void start(); };
template<typename T, bool b>
void Timer<T,b>::start()
{ \* *** \*}
我之所以发布这个答案,是因为我不想使用部分专门化,而只是定义类的外部行为。
一个完整的可行示例:
typedef std::integral_constant<bool, true> true_type;
typedef std::integral_constant<bool, false> false_type;
struct Time_unit {
};
struct time_unit_seconds : public Time_unit {
using type = std::chrono::seconds;
};
struct time_unit_micro : public Time_unit {
using type = std::chrono::microseconds;
};
template<typename T, bool B = false>
struct enable_if {
};
template<typename T>
struct enable_if<T, true> {
const static bool value = true;
};
template<typename T,
bool b = enable_if<T,
std::is_base_of<Time_unit,
T>::value
>::value>
struct Timer {
int start();
};
template<typename T, bool b>
int Timer<T, b>::start() { return 1; }
int main() {
Timer<time_unit_seconds> t;
Timer<time_unit_micro> t2;
// Timer<double> t3; does not work !
return 0;
}
https://stackoverflow.com/questions/48045559
复制