优势与静态成员函数
替换为static const成员我跨代码来这样从程序员本人高度方面:优势与静态成员函数
class BigClass {
using MyId = uint32_t;
static constexpr MyId INVALID_ID() { return std::numeric_limits<MyId>::max();};
class SmallClass {
/* Constructor, etc. */
MyId id = INVALID_ID(); /* Default value */
};
};
是否有任何明显的优势,定义INVALID_ID()为函数而不是作为一个静态常量变量?
问题static constexpr variable vs function与我的问题完全相同(我使用uint32_t
作为示例,但我发现其他类型的问题也很有趣)。但是,我对这个问题的答案并不满意。在阅读了这里的一些答案之后,我相信使用函数比使用简单模板更有优势。
我没有看到任何优势。我宁愿将INVALID_ID
声明为一个const(constexpr)而不是函数,因为函数调用会让读者想知道正在进行什么样的计算。
类似的问题被问到这里:https://*.com/questions/16287776/static-constexpr-variable-vs-function?noredirect=1&lq=1 –
声明是一个constexpr函数其中有零动态计算,而不是在任何其他声明看到一个constexpr任何东西 – ZivS
这与线程安全和静态初始化命令失败有关。如果在单独的翻译单元中定义了两个相互依赖的静态变量(一个需要另一个翻译单元的值来构建自身),则无法保证它们将被初始化的顺序。
使用包装函数和C++ 11保证编译器将围绕其初始化放置必要的线程锁,函数local static将对该函数进行并发调用,等待变量在继续执行之前进行初始化。
你应该改变忘记做*这必须忘记与线程安全和静态初始化顺序失败*? – NathanOliver
是的,电话键盘没有在猜测我想输入什么时得到了更好的... – rubenvb
好的,我只是想检查一下你是否捣碎了不同的句子, – NathanOliver
一个问题人们试图通过更换类的静态解决具有函数的常量成员是链接器错误。
例如:
struct A {
static constexpr int a = 1;
};
void foo(int const&);
foo(A::a); // Linker error: A::a.
正确的解决方案是不拿指针或引用A::a
(如果提供的A::a
的外的线定义是不希望的):
void foo(int);
你可以拿指针。只需要定义'A :: a'。 –
@NO_NAME定义'A :: a'可能不合需要。 –
除了简单的编码用法之外,我只能看到一个真正的区别:静态常量变量只有在使用odr时才需要定义(用于以ref为例的函数中...)。问题是,如果这个规则不被遵守,你会得到一个链接时间错误,程序员可能会浪费时间搜索问题的真正原因。
当您以这种方式使用某个函数,并尝试将其作为函数调用传递给需要ref的函数时,编译时错误将立即在程序员的脸上显现,并带有明确的错误消息。所以我会说,这是更多的未来维护者友好...
对未定义函数的调用可以像使用声明的静态全局一样进行编译。这两个都会导致链接器错误。 – rubenvb
那么,因为它不是一个静态成员变量,它不需要在类之外定义。 – NathanOliver
@NathanOliver在使用ODR之前,IIRC静态常量不需要定义。 – Quentin
@Quentin Typo固定。他们可能会在这种情况下使用它。 – NathanOliver