代码之家  ›  专栏  ›  技术社区  ›  greywolf82

应用SFINAE模式与通用参考

  •  1
  • greywolf82  · 技术社区  · 6 年前

    我有以下代码:

    #include <utility>
    #include <iostream>
    #include <queue>
    #include <functional>
    #include <stdio.h>
    #include <future>
    
    class Runner {
    public:
        virtual void run() = 0;
        virtual ~Runner() {
        }
    };
    
    class Command: public Runner {
    public:
        Command() {
            std::cout << "constructor" << std::endl;
        }
        virtual void run() {
        }
    };
    
    #define EXTEND(T, F) , typename = typename std::enable_if<std::is_base_of<F, typename std::decay<T>::type>::value, typename std::decay<T>::type>::type
    #define NOT_EXTEND(T, F) , typename = typename std::enable_if<!std::is_base_of<F, typename std::decay<T>::type>::value, typename std::decay<T>::type>::type
    
    class Executor {
    private:
        std::queue<std::function<void(void)> > q;
    public:
        template<class T EXTEND(T, Runner)>
        void push(T&& toBepushed) {
            q.push(
                    std::bind(&std::decay<T>::type::run,
                            std::forward<T>(toBepushed)));
        }
        template<typename T NOT_EXTEND(T, Runner)>
        void push(T&& toBepushed) {
            q.push(std::forward<T>(toBepushed));
        }
        void perform() {
            std::function<void(void)>&& f = std::move(q.front());
            f();
        }
    };
    
    int main() {
        Executor b;
        Command c;
        b.push(c);
        b.perform();
        return 0;
    }
    

    g++-std=c++0x-O2-g3-Wall-c-fmessage length=0-MMD-MP -MF“main.d”-MT“main.o”-o“main.o”“../main.cpp”。/main.cpp:45:7:错误:模板无效条::推送(T&&)不可能 超负荷空推(T&&(被推挤){ ^~~~../main.cpp:39:7:错误:使用模板无效栏::推送(T&&)无效推力(T&&(被推挤){ ^~~~生成:**[subdir.mk:20:main.o]错误1

    我正在尝试应用SFINAE,以便根据所使用的类型应用push方法。如何解决?

    1 回复  |  直到 6 年前
        1
  •  3
  •   llllllllll    6 年前

    默认参数不是模板参数列表的一部分,因此 push

    这是一个典型的缺点 typename = std::enable_if_t<...> 方法相反,您应该使用 std::enable_if_t<..., int> = 0 方法

    #define EXTEND(T, F) , typename std::enable_if<std::is_base_of<F, typename std::decay<T>::type>::value, int>::type = 0
    #define NOT_EXTEND(T, F) , typename std::enable_if<!std::is_base_of<F, typename std::decay<T>::type>::value, int>::type = 0