微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

“使用命名空间栏”和“使用 Bar::Foo”有什么区别?

如何解决“使用命名空间栏”和“使用 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

enter image description here


当然,最简单的解决方案是使用 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。但由于某种原因它不起作用

Online compiler


但是 Baz::Foo 反过来可以解决问题。这让我更加困惑

using Bar::Foo;

Online compiler


那么,我的问题是:在这种情况下,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 举报,一经查实,本站将立刻删除。