【问题标题】:How can I wrap a function (std::bind) into a namespaces?如何将函数 (std::bind) 包装到命名空间中?
【发布时间】:2014-06-23 12:58:01
【问题描述】:

我想将绑定类模板包装到一个单独的命名空间中:

namespace my_space {
template<typename... R> using bind = std::bind<R...>;
}

并得到一个错误:

error: 'bind<R ...>' in namespace 'std' does not name a type.

我怎么能这样做?一个小例子可以找到here

【问题讨论】:

  • 你为什么要这样做?
  • 可以在 std::bindboost::bind 之间进行选择,并始终在您自己的命名空间中包含所需的。
  • @user1810087 随机陷阱:不要将boost::bindstd::function 混合使用,反之亦然。库代码中存在一些潜在的有害专业化!
  • @Alex,谢谢你的提示。我已经知道了,并在命名空间(和其他一些)中包装函数和绑定。我用它来避免this 错误...

标签: c++ bind wrapper


【解决方案1】:

为什么您的代码不起作用

您的代码无法编译,因为std::bind 是一个函数,而不是一个类型。您只能使用 using 为类型声明别名。

虽然g++ 诊断并不是最好的,但Clang++ 会出现given you 以下错误:

错误:需要一个类型

这更清楚*。

你能做什么

谢天谢地,您可以使用以下命令导入 std::bind 名称:

namespace my_space {
    using std::bind;
}

Live demo

具体定义如下:

§7.3.3/1using 声明 [namespace.alias]

using-declaration 将名称引入到 using-declaration 出现的声明性区域中。

*个人意见。

【讨论】:

  • 为什么“不那么冗长”意味着“更清晰”?两条消息的要点是相同的。
  • Clang 和 gcc 诊断消息的含义相同,但 gcc 更冗长。我不明白为什么不那么冗长的 clang 的信息对你来说看起来更清晰。
  • @Ruslan 哦,不。我不是那个意思。 GCC 实际上是 less verbose 而不是 Clang++,但是当 Clang++ 正确识别问题(带有“预期类型”的消息)时,GCC 返回一个神秘的错误(可能只是对我来说):“'bind ' 在命名空间 'std' 中没有命名类型”,这几乎表明您没有包含正确的标头。
【解决方案2】:

我不知道您是否可以使用它,但另一种方法可能是通过完美转发进行包装。任何好的编译器都会优化包装器。

namespace my_space {
    template<class... Args>
    auto bind(Args&&... args) -> decltype( std::bind(std::forward<Args>(args)...) )
    {
        return std::bind(std::forward<Args>(args)...);
    }
}

在 C++14 中,您甚至可以删除 -&gt; decltype( std::bind(std::forward&lt;Args&gt;(args)...) ) 部分。

可以在here找到一个工作示例

【讨论】:

    【解决方案3】:

    如果您确实保留原始模板参数,那么只需将名称带入:

    namespace my_space {
      using std::bind;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-03-10
      • 1970-01-01
      • 2021-04-19
      • 1970-01-01
      • 2019-12-28
      • 2013-06-09
      • 1970-01-01
      • 1970-01-01
      • 2014-06-24
      相关资源
      最近更新 更多