gpt4 book ai didi

c++11 - 仅 header 库中的函数对象与函数

转载 作者:行者123 更新时间:2023-12-02 04:55:36 27 4
gpt4 key购买 nike

我正在编写一个我想只保留标题的库。在代码中我有这样的东西:

// 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

我看到两种不同的方式来拥有一个名为“quux::foo”的可调用实体:一个名为 foo 的常量对象(#if 1 - 分支)或一个名为 foo 的函数,它将它的参数转发给一个 Foo 对象(#else 分支)。我应该更喜欢哪个版本? const 对象具有内部链接,因此如果 header 包含在多个翻译单元中,则不会出现链接器错误。这两种方法之间有什么显着差异吗?

最佳答案

当你调用一个函数时,你的函数对象没有状态,我会选择函数接口(interface)。

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

其次,因为函数对象很奇怪。它们不能转换为函数指针(在你的情况下没有充分的理由),例如(注意你可以用更多样板修复它)。只有当简单的解决方案不够用时,奇怪的解决方案才是一个好主意:在这种情况下,简单的完美转发功能更简单。

最后,您可能希望使您的函数完美向前,并让 T&& 右值提供在最外层 API 级别返回 T 的函数。这可以延长临时对象的生命周期以传递您的函数。

关于c++11 - 仅 header 库中的函数对象与函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22693241/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com