在模板化 class 的模板方法中重载 std::function 参数

Overloading a std::function parameter in templated method in templated class

我在 class 模板专业化中为模板化方法制作专用模板时遇到问题。

假设我有以下代码:

#include <functional>

template<typename T>
class myClass {
public:
    T bar() {
        return T();
    }

    template<typename P>
    bool foo(std::function<P(T)> g) {
        g(bar());
        return true;
    }
};

如果我想为 myClass<void> 专门化函数 bar,我会这样做:

template<> void myClass<void>::bar() {

}

但是当我尝试以同样的方式专门化 foo 时,我得到一个编译器错误,指出 error: invalid parameter type ‘void’ 并指向 foo.

的原始定义
template<>
template<typename P>
bool myClass<void>::foo(std::function<P(void)> g) {
    bar();
    g();
    return true;
}

有没有人有什么建议,我做错了什么?

不完全是专业化...当 T 不是 void 时,您可以使用 SFINAE (std::enable_if) 激活您的 foo() 版本并激活另一个版本foo()Tvoid.

以下是一个完整的工作示例

#include <iostream>
#include <functional>

template <typename T>
class myClass
 {
   public:
      T bar()
       { return {}; }

      template <typename P, typename U = T>
      typename std::enable_if<false == std::is_same<U, void>::value,
               bool>::type foo (std::function<P(U)> const & g)
       { g(bar()); return true; }

      template <typename P, typename U = T>
      typename std::enable_if<true == std::is_same<U, void>::value,
               bool>::type foo (std::function<P()> const & g)
       { bar(); g(); return false; }
 };

template<>
void myClass<void>::bar ()
 { }

int main()
 {
   myClass<int>   mci;
   myClass<void>  mcv;

   std::function<long(int)> fli { [](int i){ return long(i); } };
   std::function<short()>   fsv { [](){ return 0; } };

   std::cout << mci.foo(fli) << std::endl; // print 1
   std::cout << mcv.foo(fsv) << std::endl; // print 0
 }