默认参数,如果默认可构造

Gui*_*cot 2 c++ templates sfinae c++11

我有一个小问题,我的代码有效,但它并不理想.

我有一个函数,它以谓词作为参数.我想支持这些语法:

myClass.foo([](auto param){ return true; }); // predicate sent as parameter
myClass.foo<PredicateType>(); // predicate type sent as template argument
myClass.foo(); // default predicate took
Run Code Online (Sandbox Code Playgroud)

但是,为了做到这一点,我重复了这样的功能:

struct MyClass {
    template<typename Predicate = DefaultPredicate&&, std::enable_if_t<std::is_default_constructible<detail::decay_t<Predicate>>::value, int> = 0>
    void foo(Predicate&& p = std::decay_t<Predicate>{}) {
        // stuff...
    }

    template<typename Predicate, std::enable_if_t<!std::is_default_constructible<detail::decay_t<Predicate>>::value, int> = 0>
    void foo(Predicate&& p) {
        // exact same stuff...
    }
};
Run Code Online (Sandbox Code Playgroud)

有没有办法在不重复我的代码的情况下执行此操作?理想的是拥有一个功能.我怎么能这样做,最好是在c ++ 11?

T.C*_*.C. 5

只是删除无意义的SFINAE和同样毫无意义的decay:

struct MyClass {
    template<typename Predicate = DefaultPredicate>
    void foo(Predicate&& p = Predicate{}) {
        // stuff...
    }    
};
Run Code Online (Sandbox Code Playgroud)

默认函数参数是单独实例化的,并且仅在实际需要时才实例化.