对我来说有些事情不太好用。这是声明一个只接受浮点模板参数的类的方法吗?
RaycastHit hit = new RaycastHit();
Physics.Raycast(touch.position, touch.position, out hit);
if (hit.collider == GameObject.FindGameObjectWithTag("Sphere0"))
{
selectedObject = GameObject.FindGameObjectWithTag("Sphere0");
}
我无法定义此类之外的方法。不编译,不确定原因
答案 0 :(得分:1)
嗯......不完全是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>
{
// ...
};
是针对两个版本(两个不同的部分特化)开发的,第一个是浮点类型,第二个是整数类型。并且可以轻松扩展。
答案 1 :(得分:0)
您还可以使用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
模板参数。
答案 2 :(得分:0)
确实,这样的事情对我有用(感谢 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;
}