隐藏 constexpr 计算的最佳方法

Best way to hide constexpr calculations

我想创建一个 constexpr 参数结构。它的几个成员将由 constexpr 函数计算。 喜欢:

class Params {
public:
    static constexpr size_t featureWinW{ 7 };
    static constexpr size_t featureWinH{ 7 };

private:
    static constexpr size_t getKernelSize()
    {
        //complex calculation
        return 20;
    }

public:
    static constexpr size_t kernelSize{ getKernelSize() };
}

我知道getKernelSize好像是在class之外定义的,所以代码是错误的:

error: ‘static constexpr size_t Params::getKernelSize()’ called in a constant expression before its definition is complete

我应该如何重新格式化我的代码以使其有效,即使是带有类似私有计算函数的专用命名空间也不发送垃圾邮件?

在 C++ 中,有许多事情要保留 "hidden" 供内部使用,但不能合理地使用 static class 成员来做。处理这些事情的标准习惯用法是创建一个名为 detail 的命名空间或类似的东西来将它们粘贴进去。你应该在这里使用这个习惯用法。

C++20 模块可能会为我们提供一种更有效的方法来标记供内部使用的数据,但在那之前,细节命名空间是最好的选择。

你可以考虑朋友帮手class:

class ParamsHelper {
    friend class Params; // friend declaration + forward class declaration
    static constexpr int getKernelSize()
    {
        //complex calculation
        return 20;
    }
};

class Params {
public:
    static constexpr int featureWinW{ 7 };
    static constexpr int featureWinH{ 7 };

    static constexpr int kernelSize{ ParamsHelper::getKernelSize() };
};

可以考虑使用 Lambda:

class Params {
public:
    static constexpr std::size_t featureWinW{ 7 };
    static constexpr std::size_t featureWinH{ 7 };
    static constexpr std::size_t kernelSize{
        [](){
            //complex calculation
            return 20;
        }(); //  immediately called.
     };
};

Demo