不能在C++中重载构造函数

dsc*_*atz 5 c++ c++11

我正在做一个只移动的等价物std::function.move_function包含指向基类的指针,move_function_base该类型会删除基础的仿函数类型.move_function_imp继承move_function_base并保存类型化的底层函子.move_function_imp定义如下:

template<class F, class ReturnType, class... ParamTypes>
class move_function_imp : public move_function_base<ReturnType, ParamTypes...> {

  typename std::remove_reference<F>::type f_;

public:
  virtual ReturnType callFunc(ParamTypes&&... p) override {
    return f_(std::forward<ParamTypes>(p)...);
  }
  explicit move_function_imp(const F& f) : f_(f) {}
  explicit move_function_imp(F&& f) : f_(std::move(f)) {}

  move_function_imp() = delete;
  move_function_imp(const move_function_imp&) = delete;
  move_function_imp& operator=(const move_function_imp&) = delete;
};
Run Code Online (Sandbox Code Playgroud)

当我使用它时,我得到一个错误,构造函数不能相互重载.我究竟做错了什么?完整代码位于此处.


编辑:从ideone链接粘贴的错误:

prog.cpp: In instantiation of ‘class move_function_imp<main()::__lambda0&, void>’:
prog.cpp:39:30:   required from ‘move_function<ReturnType(ParamTypes ...)>::move_function(F&&) [with F = main()::__lambda0&; ReturnType = void; ParamTypes = {}]’
prog.cpp:62:38:   required from here
prog.cpp:20:12: error: ‘move_function_imp<F, ReturnType, ParamTypes>::move_function_imp(F&&) [with F = main()::__lambda0&; ReturnType = void; ParamTypes = {}]’ cannot be overloaded
   explicit move_function_imp(F&& f) : f_(std::move(f)) {}
            ^
prog.cpp:19:12: error: with ‘move_function_imp<F, ReturnType, ParamTypes>::move_function_imp(const F&) [with F = main()::__lambda0&; ReturnType = void; ParamTypes = {}]’
   explicit move_function_imp(const F& f) : f_(f) {}
            ^
prog.cpp:19:12: error: ‘move_function_imp<F, ReturnType, ParamTypes>::move_function_imp(const F&) [with F = main()::__lambda0&; ReturnType = void; ParamTypes = {}]’, declared using local type ‘main()::__lambda0’, is used but never defined [-fpermissive]
Run Code Online (Sandbox Code Playgroud)

Toc*_*ocs 1

花了一点时间,但我明白

答案完整性的片段。

template <class>
struct remove_reference_except_function {};

template <class R, class... Args>
struct remove_reference_except_function<R(&)(Args...)>
{
    typedef R(&type)(Args...);
};

template <class R, class... Args>
struct remove_reference_except_function<R(&)(Args......)> //varardic function
{
    typedef R(&type)(Args......);
};
//I dont think you can have an rvalue reference to a function? Or can you dereference a non-capturing lambda?
template <class T>
struct remove_reference_except_function<T &>
{
    typedef T type;
};

template <class T>
struct remove_reference_except_function<T &&>
{
    typedef T type;
}; 

template< class ReturnType, class... ParamTypes>
struct move_function_base{
  virtual ReturnType callFunc(ParamTypes... p) = 0;
};

template<class F, class ReturnType, class... ParamTypes>
class move_function_imp : public move_function_base<ReturnType, ParamTypes...> {

  //Using std::remove_reference on a normal function gives you an invalid type for declaring a variable. Hence the custom reference removal
  typename remove_reference_except_function<F>::type f_; 

public:
  virtual ReturnType callFunc(ParamTypes... p) override {
    return f_(std::forward<ParamTypes>(p)...);
  }
  explicit move_function_imp(const typename std::remove_reference<F>::type& f) : f_(f) {}
  explicit move_function_imp(typename std::remove_reference<F>::type&& f) : f_(std::move(f)) {}

  move_function_imp() = delete;
  move_function_imp(const move_function_imp&) = delete;
  move_function_imp& operator=(const move_function_imp&) = delete;
};
Run Code Online (Sandbox Code Playgroud)

正如人们指出的那样,您的主要问题是模板参数折叠为相同类型,从而导致重载错误,因此我使用普通的 std::remove_reference 来解决这个问题。

此外,move_function_imp 的 callFunc 中存在恶意右值引用。

我必须创建一个自定义的remove_reference来声明f_,因为如果您从正常创建的函数(在我的示例中为ff)中删除了引用,则会出现编译错误。

老实说,如果有人提出更正,我会因为工作而感到有点眼花缭乱,我很高兴听到他们的声音。