C++ std::函数签名指针与指针引用=没有区别?

C++ std::函数签名指针与指针引用=没有区别?,c++,function,pointers,c++11,C++,Function,Pointers,C++11,下面是代码示例: #include <string> #include <functional> struct Foo {}; typedef bool func_type(Foo *&, const std::string&); typedef std::function<bool(Foo*&, const std::string&)> FunctionalType; bool f(Foo *, const s

下面是代码示例:

 #include <string>
 #include <functional>

 struct Foo {};
 typedef bool func_type(Foo *&, const std::string&);
 typedef std::function<bool(Foo*&, const std::string&)> FunctionalType;

 bool f(Foo *, const std::string&)
 {
 }

 int main()
 {
 #if 1
   func_type *func;
   func = f;
 #else
   FunctionalType f2;
   f2 = f;
#endif
}
  • 为什么它编译时没有错误(至少有gcc 5.2和clang 3.7)

  • 如何修复它,使
    std::function
    不接受
    f
    进行转换


  • std::function
    定义为一种类型,其对象可以表示任何可以用参数调用的函数。,其返回值可转换为
    R

    由于可以使用类型为
    T*
    的左值作为第一个参数调用函数
    f
    (这是
    Foo*&
    强加的要求),因此它是存储在
    std::function
    中的有效函数


    据我所知,无法抑制这种行为。

    std::function
    是一个类型擦除容器,包含可调用的内容

    它将存储任何C++类型的实例,该实例可以用“兼容”签名复制、销毁和调用。 在本例中,签名是

    bool(Foo*&,const std::string&)

    核心思想是,当
    std::function
    类型的
    R(Args…
    部分中的
    Args…
    Foo*&
    const std::string&
    时,这些参数可以传递给期望
    Foo*
    const std::string&
    的函数


    std::function
    基于兼容性工作,而不是签名的精确匹配

    如果你真的,真的需要禁止不带参考资料的东西:

    template<class T>
    struct reference_only {
      T& t;
      operator T&(){ return t; }
      operator T()=delete;
      reference_only(T& tin):t(tin){}
    };
    
    模板
    仅限结构引用{
    T&T;
    运算符T&({return T;}
    运算符T()=删除;
    仅供参考(T&tin):T(tin){
    };
    
    然后使用:

    typedef std::function<void(reference_only<Foo*>)> FunctionalType;
    
    typedef std::function FunctionalType;
    
    它不喜欢转换为值类型,但接受转换为引用类型(在本例中为
    Foo*&


    ,.

    我将另一个答案标记为答案,因为它为(2)提供了一些解决方法。
    typedef std::function<void(reference_only<Foo*>)> FunctionalType;