为什么不能从std :: addressof <int>解析模板参数?

时间:2017-09-12 19:23:27

标签: c++ templates stl

Clang和GCC(MSVC除外)在将curr = np.zeros((660,512, 1)) regions = np.random.uniform(1, 200, size=(1, 5, 2)) regions = regions.astype(np.int32, copy=False) for r in regions: cv2.fillPoly(curr, [r], [190]) while(1): cv2.imshow('Terry Martin', curr) k= cv2.waitKey(1) & 0xFF if k == 27: cv2.imwrite('FillPloy.jpg', curr) break cv2.destroyAllWindows() 作为参数传递给模板函数时无法解析模板参数。以下是此类错误的示例:

a=int(input('number! '))
accuracy=10 #number of decimals
s=0
step=1
for i in range(accuracy+1):
    while (s+step)**2<=a:
        s+=step
    step=step/10
s=format(s,'.'+str(accuracy)+'f')
print(s)

锵:

std::addressof<int>

GCC

std::vector<int> v{1,2,3,4,5};
std::vector<int*> pv(iv.size());
std::transform(v.begin(), v.end(), pv.begin(), std::addressof<int>);

如果参数是<source>:8:5: error: no matching function for call to 'transform' std::transform(iv.begin(), iv.end(), piv.begin(), std::addressof<int>); ^~~~~~~~~~~~~~ /opt/compiler-explorer/clang-5.0.0/bin/../include/c++/v1/algorithm:2028:1: note: candidate template ignored: couldn't infer template argument '_UnaryOperation' transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) ^ ,那么该错误就有意义,因为/opt/compiler-explorer/gcc-7.2.0/include/c++/7.2.0/bits/stl_algo.h:4295:5: note: template argument deduction/substitution failed: <source>:8:74: note: could not resolve address from overloaded function 'addressof<int>' std::transform(iv.begin(), iv.end(), piv.begin(), std::addressof<int>); ^ 模板参数不明确。但是,编译器不需要推导std::addressofUnaryOperator的内容,除此之外没有歧义。

这是我期望的一个实例(编译Clang 5和GCC 7.2):

T

我的疑问是:为什么std::addressof<int>可以从template <typename T> T* addrof(T& a) { return __builtin_addressof(a); } template <typename F, typename T> void foo(F f, T& a) { f(a); } int main() { int a = 42; foo(addrof<int>, a); } 中推断std::transform模板参数?

1 个答案:

答案 0 :(得分:5)

是的,它在你的例子中不起作用,因为每个模板std::addressof有两个重载,因为C ++ 17(一个获取地址,一个删除的版本采用右值引用),它是不明确的编译器选哪一个。最简单的解决方案是使用lambda:

#include <vector>
#include <algorithm>

void foo() {
   std::vector<int> v{1,2,3,4,5};
   std::vector<int*> pv(v.size());
   std::transform(v.begin(), v.end(), pv.begin(), 
                  [](int& i) { return std::addressof(i);});
}

这些重载列于此处:http://en.cppreference.com/w/cpp/memory/addressof

另一种选择是使用演员,但它只是丑陋,你应该更喜欢Lambdas!然而,将提供完整性:

#include <vector>
#include <algorithm>

void foo() {
   std::vector<int> v{1,2,3,4,5};
   std::vector<int*> pv(v.size());

   std::transform(v.begin(), v.end(), pv.begin(), 
                  static_cast<int* (*)(int&) >(std::addressof<int>));
}