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

如何强制C从全局命名空间中选择一个函数?,第1张

概述我有一个容器,并希望依赖于使用我的库的人来确保函数可用于基础value_type(即将到来的示例中的pow()).我希望编译器根据其签名在具有相同名称的成员函数内使用该函数. 我试图创建一个最小的例子: #include <iostream>#include <cmath>using std::pow;template <typename T>struct container { 我有一个容器,并希望依赖于使用我的库的人来确保函数可用于基础value_type(即将到来的示例中的pow()).我希望编译器根据其签名在具有相同名称的成员函数内使用该函数.

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

#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;}

容器<>提供了一个pow()方法,它应该依赖于可从全局命名空间中的底层类型获得的pow().

这应该有助于使用自定义数字类型.即库用户应该能够定义自己的类型,这些类型的行为类似于数字,并为其类型提供pow()函数,以使其成为容器<>兼容.

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

c++ -std=c++11 pow.cpp -o powpow.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 {        ^

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

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

该程序产生预期的输出:

c++ -std=c++11 pow.cpp -o pow./pow81^0.25 = 3

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

解决方法 你需要在pow函数中引入std :: pow函数.如果ADL失败,这允许编译器回退到std :: pow

#include <iostream>#include <cmath>template <typename T>struct container {    T value;    container<T> pow(T const exp) const {        using std::pow;        return {pow(this->value,exp)};    }};int main() {    container<double> value{81.};    std::cout << value.value << "^0.25 = " << value.pow(.25).value << '\n';    return 0;}

Live Example

这与building a custom swap function时的 *** 作相同.您可以看到它与具有自己的pow here的类一起工作

编辑那些不了解查找的人.了解它们之间的区别非常重要

T func(T a,T b){  using std::pow;  return pow(a,b);}

T func(T a,T b){  return std::pow(a,b);}

后者总是调用std :: pow(),如果T不能转换为double(或者std :: complex< double>如果< complex>是#included),则会失败.前者将使用ADL找到最匹配的pow()函数,它可能是std :: pow.

总结

以上是内存溢出为你收集整理的如何强制C从全局命名空间中选择一个函数?全部内容,希望文章能够帮你解决如何强制C从全局命名空间中选择一个函数?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/1217034.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存