c++ 在函数内部定义结构体有什么“惩罚”吗?

mm5n2pyu  于 2022-12-24  发布在  其他
关注(0)|答案(5)|浏览(134)

只是出于好奇..
正如标题所说:在函数内部定义结构体有什么“惩罚”吗?(比如 * 性能、内存、糟糕的编程实践 * 等)
P.S.我知道,在函数内部定义(非模板)函子是一种常见的做法,但仍然...)

x4shl7ld

x4shl7ld1#

在C11中,没有--没有惩罚。我甚至认为这是一个非常好的风格,不污染任何“更可见”的作用域与您的实现细节,除非,当然,你想在其他地方重用该函子。然而,lambda本质上是这个想法的一个浓缩形式,和通常应该是首选如果你只是使用结构体作为函子。对于所有类型的数据,它是非常好的,尽管它通常在那方面与std::pairstd::tuple竞争。
在C
03中,你不能使用这样的结构体作为模板参数,因为那些参数需要有外部链接(尽管Visual Studio允许你这样做)。在多态接口中使用这样的结构体仍然是有用的。

a14dhokn

a14dhokn2#

由于这纯粹是一个可见性问题,我无法想象会有性能或内存损失的合理场景。

hjqgdpho

hjqgdpho3#

如果你使用的是C++03,那么从技术上讲你不能使用一个本地定义的结构作为模板参数,但是一些编译器(即MSVC)允许这样做。

zazmityj

zazmityj4#

我知道你问的是性能,但我想知道另一个问题。你是想同时使用C和C++,还是只使用其中的一种语言?我大胆地猜测,你想在函数中定义一个结构,以达到作用域或隐藏结构的目的。
对于C语言,你可以通过在一个单独的模块中定义和声明结构并使它们成为静态来隐藏东西。然后,你可以提供访问函数,就像你为C类的成员所做的那样。你可以在一个.h文件中为那些需要访问结构的模块包括函数声明。
如果这是针对C
的,那么创建一个类并使结构私有化或受保护,沿着编写适当的get/set/manipulate方法,就可以完成其余的工作。
如果你编辑了你最初的帖子,并扩展了你问这个问题的原因,你已经问了一个很好的问题。

lsmepo6l

lsmepo6l5#

如果某些成员函数基于编译时约束不可调用,则不能使用本地定义的结构生成模板化类型的对象。
示例:

template<typename T>
concept C = requires(T t) { { t.unsupported() }; };

template <typename T>
struct X {
    void unsupported() { static_assert(std::is_void_v<T>); }
};
static_assert(C<X<int>>);

template <typename T>
C auto make()
{
    struct Y {
        void unsupported() { static_assert(std::is_void_v<T>); }
    };
    return Y{};
}

int main()
{
    C auto x = X<int>{};      // compiles fine
    C auto y = make<int>();   // error: static assertion failed
    return 0;
}

相关问题