如何解决“使用命名空间栏”和“使用 Bar::Foo”有什么区别?
# https://stackoverflow.com/a/50714300/7200745
from scipy.spatial import delaunay
import numpy as np
def alpha_shape(points,alpha,only_outer=True):
"""
Compute the alpha shape (concave hull) of a set of points.
:param points: np.array of shape (n,2) points.
:param alpha: alpha value.
:param only_outer: boolean value to specify if we keep only the outer border
or also inner edges.
:return: set of (i,j) pairs representing edges of the alpha-shape. (i,j) are
the indices in the points array.
"""
assert points.shape[0] > 3,"Need at least four points"
def add_edge(edges,i,j):
"""
Add an edge between the i-th and j-th points,if not in the list already
"""
if (i,j) in edges or (j,i) in edges:
# already added
assert (j,i) in edges,"Can't go twice over same directed edge right?"
if only_outer:
# if both neighboring triangles are in shape,it's not a boundary edge
edges.remove((j,i))
return
edges.add((i,j))
tri = delaunay(points)
edges = set()
# Loop over triangles:
# ia,ib,ic = indices of corner points of the triangle
for ia,ic in tri.vertices:
pa = points[ia]
pb = points[ib]
pc = points[ic]
# Computing radius of triangle circumcircle
# www.mathalino.com/reviewer/derivation-of-formulas/derivation-of-formula-for-radius-of-circumcircle
a = np.sqrt((pa[0] - pb[0]) ** 2 + (pa[1] - pb[1]) ** 2)
b = np.sqrt((pb[0] - pc[0]) ** 2 + (pb[1] - pc[1]) ** 2)
c = np.sqrt((pc[0] - pa[0]) ** 2 + (pc[1] - pa[1]) ** 2)
s = (a + b + c) / 2.0
area = np.sqrt(s * (s - a) * (s - b) * (s - c))
circum_r = a * b * c / (4.0 * area)
if circum_r < alpha:
add_edge(edges,ia,ib)
add_edge(edges,ic)
add_edge(edges,ic,ia)
return edges
def find_edges_with(i,edge_set):
i_first = [j for (x,j) in edge_set if x==i]
i_second = [j for (j,x) in edge_set if x==i]
return i_first,i_second
def stitch_boundaries(edges):
edge_set = edges.copy()
boundary_lst = []
while len(edge_set) > 0:
boundary = []
edge0 = edge_set.pop()
boundary.append(edge0)
last_edge = edge0
while len(edge_set) > 0:
i,j = last_edge
j_first,j_second = find_edges_with(j,edge_set)
if j_first:
edge_set.remove((j,j_first[0]))
edge_with_j = (j,j_first[0])
boundary.append(edge_with_j)
last_edge = edge_with_j
elif j_second:
edge_set.remove((j_second[0],j))
edge_with_j = (j,j_second[0]) # flip edge rep
boundary.append(edge_with_j)
last_edge = edge_with_j
if edge0[0] == last_edge[1]:
break
boundary_lst.append(boundary)
return boundary_lst[0]
#generating of random points
N = 1000
r = 1 - 2*np.random.random((N,2))
r_norm = np.linalg.norm(r,axis=1)
points = r[r_norm <= 1]
plt.figure(figsize=(10,10))
plt.scatter(points[:,0],points[:,1],color='k',s=1)
# Computing the alpha shape
edges = alpha_shape(points,alpha=1,only_outer=True)
#order edges
edges = stitch_boundaries(edges)
plt.axis('equal')
edge_points = np.zeros((len(edges),2))
k=0
for i,j in edges:
edge_points[k,:] = points[[i,j],0][0],points[[i,1][0]
k += 1
plt.plot(edge_points[:,edge_points[:,1])
#theoretical/expected edges
# xx = np.linspace(-1,1,100)
# yy_upper = np.sqrt(1 - xx**2)
# yy_lower = -np.sqrt(1 - xx**2)
# plt.plot(xx,yy_upper,'r:')
# plt.plot(xx,yy_lower,'b:')
编译器无法确定要使用哪个 #include <iostream>
class Foo {
};
namespace Bar {
struct Foo {
};
}
namespace Baz
{
void baz(const Foo &)
{
std::cout << "Hello";
}
}
int main()
{
Baz::baz(Bar::Foo());
}
并产生错误:
Foo
当然,最简单的解决方案是使用 main.cpp: In function 'int main()':
main.cpp:23:19: error: invalid initialization of reference of type 'const Foo&' from expression of type 'Bar::Foo'
23 | Baz::baz(Bar::Foo());
| ^~~~~
main.cpp:15:14: note: in passing argument 1 of 'void Baz::baz(const Foo&)'
15 | void baz(const Foo &)
|
或 ::Foo
,但我想用 O(1) 行代码修复所有可能的歧义。
我的第一个想法是 ::Baz::Foo
命名空间内的 using namespace Bar
:
Baz
using-declaration:使命名空间 ns_name 中的符号名称可用于非限定查找,就像在与此 using-声明出现的位置相同的类作用域、块作用域或命名空间中声明一样。
我希望所有 namespace Baz
{
using namespace Baz;
//...
名称都成为 Bar
命名空间的一部分,并且不合格的查找更喜欢 Baz
。但由于某种原因它不起作用
但是 Baz::Foo
反过来可以解决问题。这让我更加困惑
using Bar::Foo;
那么,我的问题是:在这种情况下,namespace Baz
{
using Bar::Foo;
和 using namespace Bar
之间有什么区别?
解决方法
using namespace Bar::Foo
会假设 Bar::Foo 是一个命名空间,并将该命名空间中的所有内容导入当前范围,例如
namespace Bar { namespace Foo { ... all names from this namespace would be imported ... } }
using Bar::Foo
会将 class Bar::Foo 导入作用域:
namespace Bar { class Foo {...} }
并且如果您在 class Bar 中嵌套了 class Foo 并且想在没有类说明符的情况下使用它,那么使用将如下所示:
class Bar {
public:
class Foo {};
};
using Foo = Bar::Foo;
// ...
// ... use Foo instead of Bar::Foo ...
,
cppreference 是您的朋友。
关于using namespace ns_name;
,它读
using-directive:从 using 指令之后的任何名称的非限定 name lookup 的角度来看,直到它出现的范围结束,每个名称都来自 ns_name 是可见的,就好像它是在最近的包含 using 指令和 ns_name 的封闭命名空间中声明的一样。
关于using ns_name::name;
,它读
using-declaration:使 unqualified lookup 可以访问命名空间 ns_name 中的符号 name,就像在相同的类作用域、块作用域中声明一样,或命名空间作为此 using 声明出现的位置。
看起来很复杂,其实不然。此外,学习以这种方式解释的事物(我会说这接近于标准语言)在深入 C++ 的深度时是有回报的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。