C++11 函数对象与仅标题库中的函数

C++11 函数对象与仅标题库中的函数,c++11,C++11,我正在写一个我只想保留标题的库。在代码中,我有如下内容: // Wrapper.h #ifndef INCLUDED_WRAPPER_H #define INCLUDED_WRAPPER_H namespace quux { template <typename T, typename U> class Wrapper { T m_t; U m_u; public: Wrapper(T const & t, U const & u) : m_t(t),

我正在写一个我只想保留标题的库。在代码中,我有如下内容:

// Wrapper.h
#ifndef INCLUDED_WRAPPER_H
#define INCLUDED_WRAPPER_H

namespace quux {

template <typename T, typename U>
class Wrapper
{
  T m_t;
  U m_u;
public:
  Wrapper(T const & t, U const & u) : m_t(t), m_u(u) { }

  // ...
};

} // namespace quux

#endif // INCLUDED_WRAPPER_H

// Foo.h
#ifndef INCLUDED_FOO_H
#define INCLUDED_FOO_H

#include <type_traits>

#include "Wrapper.h"

namespace quux {

// if some type is special, then there will be a specialization of this
// struct derived from std::true_type
template <typename T> struct is_special : std::false_type { };

class Foo
{
  template <typename T>
  Wrapper<Foo, T> impl(T const & t, std::true_type ) const
  {
    return Wrapper<Foo, T>(*this, t);
  }

  template <typename T>
  T const & impl(T const & t, std::false_type ) const;
  {
    return t;
  }
public:

  template <typename T>
  auto operator()(T const & t) const // using automatic return type deduction
  {
    return impl(t, is_special<T>());
  }

};

#if 1
Foo const foo;
#else
template <typename T>
auto foo(T const & t) // using automatic return type deduction
{
  return Foo()(t);
}
#endif

} // namespace quux

#endif // INCLUDED_FOO_H
//Wrapper.h
#如果不包括包装材料
#定义包含的包装器
名称空间quux{
模板
类包装器
{
T m_T;
嗯!;
公众:
包装器(T常量和T,U常量和U):m_T(T),m_(U){}
// ...
};
}//名称空间quux
#endif//包含在包装中
//福安
#ifndef包括_FOO_H
#定义包含的\u FOO\u H
#包括
#包括“Wrapper.h”
名称空间quux{
//如果某个类型是特殊的,则会有此类型的专门化
//从std::true\u类型派生的结构
模板结构是_特殊的:std::false_类型{};
福班
{
模板
包装器impl(T const&T,std::true_type)const
{
返回包装(*this,t);
}
模板
常数与impl(常数与时间,标准::假类型)常数;
{
返回t;
}
公众:
模板
自动运算符()(T const&T)const//使用自动返回类型推断
{
return impl(t,is_special());
}
};
#如果1
富康富;
#否则
模板
auto foo(T const&T)//使用自动返回类型推断
{
返回Foo()(t);
}
#恩迪夫
}//名称空间quux
#endif//包含在\u FOO\u H中

我看到了两种不同的方法来创建一个名为“qux::foo”的可调用实体:一个名为foo的常量对象(if 1-branch)或一个名为foo的函数,该函数将其参数转发给一个foo对象(else-branch)。我应该选择哪个版本?const对象具有内部链接,因此如果头包含在多个翻译单元中,则不会出现链接器错误。这两种方法之间有什么显著的区别吗?

当您调用一个函数,并且您的函数对象没有状态时,我将使用函数接口

首先,因为函数可以重载,而函数对象不能在函数对象的主体之外。您可能希望对功能启用ADL扩展

第二个原因是函数对象是wierd。例如,它们不能转换为函数指针(在您的情况下,没有充分的理由),请注意,您可以使用更多的样板文件来解决这个问题。奇怪的解决方案只有在简单的解决方案不足时才是一个好主意:在这种情况下,简单的完美转发功能更简单

最后,您可能希望使您的函数向前完善,并让
T&
r值给出在最外层API级别返回
T
的函数。这使临时变量的生命周期扩展能够通过您的函数传递