繁体   English   中英

sfinae:enable_if条件

[英]sfinae: enable_if condition

我总是只看到enable_if与条件std :: is_integral :: value一起使用。

有没有办法在条件中使用另一个模板类的对象的成员函数的函数调用? 我正在谈论的功能应如下所示:

bool someFunc()
{
    if (QString(T::staticMetaObject.className()) == QString("Form")) {
        return true;
    }
    return false;   
}

目前无论我尝试什么,我都无法编译。

感谢你们对我的帮助。

编辑:

我的问题是更清楚更多的代码和错误消息。

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>
#include <type_traits>
#include <QDebug>

template <class T>
typename std::enable_if<Form<MainWindow>::staticThis->someFunc(),bool>::type
  is_smth (T* obj) { return true; }

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    form = new Form<MainWindow>;

    qDebug() << is_smth(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "form.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    Form<MainWindow>* form;

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

form.h

#ifndef FORM_H
#define FORM_H
#include <QObject>

class FormBase : public QObject
{
    Q_OBJECT
};

template <class T>
class Form : public FormBase
{
public:
    Form() {}

    static Form* staticThis;

    bool someFunc()
    {
        if (QString(T::staticMetaObject.className()) == QString(Form::staticMetaObject.className())) {
            return true;
        }
        return false;
    }
};

#endif // FORM_H

form.cpp

#include "form.h"
#include "mainwindow.h"

Form<MainWindow>* Form::staticThis = NULL;

错误:

'form :: staticThis'的值不能用于常量表达式typename std :: enable_if :: staticThis-> someFunc(),bool> :: type ^

我不想在st_或其他东西的enable_if函数的条件下使用。 我想用自己的功能。 我不知道如何让它发挥作用。 也许这就是为什么你会认为代码有点繁忙。 但我认为它现在应该显示我正在努力实现的目标。

再次感谢你

不确定你在寻找什么,但这里有一个使用成员函数的sfinae的例子:

#include<type_traits>

template<typename T>
std::enable_if_t<std::is_member_function_pointer<T>::value>
foo() { }

struct S {
    void bar() { }
    int i;
};

int main() {
    // compiles, for it is a member function
    foo<decltype(&S::bar)>();
    // does not compile, for it is not a member function
    //foo<decltype(&S::i)>();
}

编辑

在编辑OP之后,我用一个最小的工作示例来更新答案,该示例显示了如何以他想要的方式使用sfinae
为了做到这一点,成员函数至少由于显而易见的原因必须是constexpr

#include<type_traits>

struct S {
    static constexpr bool bar(bool b) { return b; }
};

template<bool b>
std::enable_if_t<S::bar(b)>
foo() { }

int main() {
    foo<true>();
    // fails to compile because of sfinae
    // foo<false>();
}

OP的例子远不是一个最小的例子,我想它不值得修复它。
相反,上面的那个足以解释解决方案背后的想法。

编辑

正如评论中所提到的,C ++ 11对constexpr函数有更严格的限制。
相反,自从C ++ 14以来,你可以在constexpr函数中使用更复杂的语句。
例如,下面的代码使用-std=c++14编译,而不使用-std=c++11编译:

#include<type_traits>

struct T {
    constexpr T(char c): ch{c} { }
    char ch;
};

struct S {
    static constexpr bool bar(T&& t) {
        if(t.ch == 'y') {
            return static_cast<unsigned int>(t.ch) % 2 == 0;
        } else {
            return true;
        }
    }
};

template<char c>
std::enable_if_t<S::bar(T{c})>
foo() { }

int main() {
    foo<'x'>();
    // fails to compile because of sfinae
    // foo<'y'>();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM