我有一个容器,希望依赖使用我的库的人来确保底层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;
}container<>提供了一个pow()方法,该方法应该依赖于全局命名空间中的底层类型中的pow()。
这应该是为了方便使用自定义的类数字类型。也就是说,库用户应该能够定义自己的类型,这些类型与数字一样,并为其类型提供一个pow()函数,以使其与container<>兼容。
问题是,clang和gcc都没有从全局命名空间中获取函数:
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 {
^如果我显式地使用全局命名空间,它将按预期工作:
container<T> pow(T const exp) const {
return {::pow(this->value, exp)};
}程序产生预期的输出:
c++ -std=c++11 pow.cpp -o pow
./pow
81^0.25 = 3这解决了实际问题,但我不知道为什么有必要这样做?签名匹配不应该允许编译器选择正确的函数吗?
发布于 2015-12-03 17:29:23
简单的答案是:您不强制C++从全局命名空间.(句号)中选择一个函数。
相反,您可以在与该类型相同的namespace中声明与用户定义的类型关联的任何功能,即
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)};
}
}什么时候
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。
int main()
{
container<foo::bar> value{81.};
std::cout << value.value << "^0.25 = "
<< value.pow(foo::bar{0.25}).value << '\n';
}https://stackoverflow.com/questions/34067114
复制相似问题