首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何强制C++从全局命名空间中选择函数?

如何强制C++从全局命名空间中选择函数?
EN

Stack Overflow用户
提问于 2015-12-03 13:19:15
回答 4查看 1.7K关注 0票数 4

我有一个容器,希望依赖使用我的库的人来确保底层value_type (在下面的示例中是pow())可以使用一个函数。我希望编译器在同名成员函数的内部使用该函数,基于它的签名。

我试图创建一个最小的示例:

代码语言:javascript
运行
复制
#include <iostream>
#include <cmath>

using std::pow;

template <typename T>
struct container {
    T value;

    container<T> pow(T const exp) const {
        return {pow(this->value, exp)};
    }
};

int main() {
    container<double> value{81.};
    std::cout << value.value << "^0.25 = " << value.pow(.25).value << '\n';
    return 0;
}

container<>提供了一个pow()方法,该方法应该依赖于全局命名空间中的底层类型中的pow()。

这应该是为了方便使用自定义的类数字类型。也就是说,库用户应该能够定义自己的类型,这些类型与数字一样,并为其类型提供一个pow()函数,以使其与container<>兼容。

问题是,clang和gcc都没有从全局命名空间中获取函数:

代码语言:javascript
运行
复制
c++ -std=c++11 pow.cpp -o pow
pow.cpp:11:28: error: too many arguments to function call, expected single argument 'exp', have 2 arguments
                return {pow(this->value, exp)};
                        ~~~              ^~~
pow.cpp:17:50: note: in instantiation of member function 'container<double>::pow' requested here
        std::cout << value.value << "^0.25 = " << value.pow(.25).value << '\n';
                                                        ^
pow.cpp:10:2: note: 'pow' declared here
        container<T> pow(T const exp) const {
        ^

如果我显式地使用全局命名空间,它将按预期工作:

代码语言:javascript
运行
复制
container<T> pow(T const exp) const {
    return {::pow(this->value, exp)};
}

程序产生预期的输出:

代码语言:javascript
运行
复制
c++ -std=c++11 pow.cpp -o pow
./pow
81^0.25 = 3

这解决了实际问题,但我不知道为什么有必要这样做?签名匹配不应该允许编译器选择正确的函数吗?

EN

Stack Overflow用户

发布于 2015-12-03 17:29:23

简单的答案是:您不强制C++从全局命名空间.(句号)中选择一个函数。

相反,您可以在与该类型相同的namespace中声明与用户定义的类型关联的任何功能,即

代码语言:javascript
运行
复制
namespace foo {
  struct bar      // the 'value_type'
  { 
    double x;
  };
  // define functions related to type bar in same namespace
  std::ostream& operator<<(std::ostream&s, bar x)
  {
    return s<<x.x;
  }

  foo::bar pow(foo::bar x, foo::bar y)
  {
    return {std::pow(x.x,y.x)};
  }
}

什么时候

代码语言:javascript
运行
复制
template <typename T>
struct container {
  T value;
  container<T> pow(T const&exp) const
  {
    using std::pow;
    return {pow(this->value, exp)};
  }
};

通过ADL查找T=foo::bar,通过std::pow()查找T=double

代码语言:javascript
运行
复制
int main()
{
  container<foo::bar> value{81.};
  std::cout << value.value << "^0.25 = "
            << value.pow(foo::bar{0.25}).value << '\n';
}
票数 0
EN
查看全部 4 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34067114

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档