Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何声明SFINAE类?_C++_C++11_Templates_Sfinae - Fatal编程技术网

C++ 如何声明SFINAE类?

C++ 如何声明SFINAE类?,c++,c++11,templates,sfinae,C++,C++11,Templates,Sfinae,有些东西对我不太管用。这是声明只接受浮点模板参数的类的方法吗 template <typename T, swift::enable_if<std::is_floating_point<T>::value> = nullptr> class my_float; 模板 类我的浮点数; 我无法在此类之外定义方法。没有编译,不知道为什么。。。不完全是SFINAE。。。但也许,使用模板专门化?下面是什么 template <typename T, boo

有些东西对我不太管用。这是声明只接受浮点模板参数的类的方法吗

template <typename T, swift::enable_if<std::is_floating_point<T>::value> = nullptr>
  class my_float;
模板
类我的浮点数;

我无法在此类之外定义方法。没有编译,不知道为什么。。。不完全是SFINAE。。。但也许,使用模板专门化?下面是什么

template <typename T, bool = std::is_floating_point<T>::value>
class my_float;

template <typename T>
class my_float<T, true>
 {
   // ...
 };

开发了两个版本(两种不同的部分专门化),第一个用于浮点类型,第二个用于整数类型。并且可以很容易地扩展。

您还可以使用
static\u assert
来毒害无效类型

template <typename T>
class my_float {
  static_assert(std::is_floating_point<T>::value,
    "T is not a floating point type");
  // . . .
};
模板
我的浮点数{
静态断言(std::是浮点::值,
“T不是浮点类型”);
// . . .
};
在我看来,这更直接一点

使用其他任何一种方法,例如

template <typename T, bool = std::is_floating_point<T>::value>
class my_float;

template <typename T> class my_float<T, true> { /* . . . */ };
模板
类我的浮点数;
模板类my_float{/*…*/};
my_float
是有效类型。我并不是说这是一种不好的方法,但是如果你想避免这种情况,你必须封装
my_float
在另一个模板中,以避免暴露
bool
模板参数。

事实上,类似的方法对我很有效(感谢SU3的回答)

模板
如果{},结构启用_;
模板
结构启用\u如果{
静态常量布尔值=真;
};
模板
类计时器{void start();};
模板
void Timer::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;
}
typedef std::integral_constant true_type;
typedef std::整型_常量假_类型;
结构时间单位{
};
结构时间单位秒:公共时间单位{
使用type=std::chrono::seconds;
};
结构时间单位:公共时间单位{
使用type=std::chrono::微秒;
};
模板
结构启用\u如果{
};
模板
结构启用\u如果{
常量静态布尔值=真;
};
模板
结构计时器{
int start();
};
模板
int Timer::start(){return 1;}
int main(){
定时器t;
定时器t2;
//计时器t3;不工作!
返回0;
}

@Yakk-不确定是否理解,但。。。修改答案。谢谢。是的,这就是我的意思有点琐事:至少最近(我没有检查C++17),标准的合理阅读不支持sfinae在模板类中(!)只在函数模板中;每个编译器都支持它,因此它是学术性的。我也可能是错的。只需在类主体中放置一个
静态断言
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> { /* . . . */ };
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;
}