使用以下(A)的(缺点)有哪些:
// .h
class SomeClass
{
static const struct ConstantGroup
{
int a = 1;
string b = "b";
// ... etc.
} CONSTANT;
};
// .cpp
const SomeClass::ConstantGroup SomeClass::CONSTANT;
对(B):
// .h
class SomeClass
{
static const int A;
static const string B;
// .. etc.
};
// .cpp
const int SomeClass::A = 1;
const string SomeClass::B = "b";
...对于某些组相关的静态类常量?假设不涉及模板,并且常量包含简单类型(POD或字符串)。
到目前为止,我看到以下有利于(A)的优点:
static const auto & SHORTHAND = SomeClass::LONG_NAME_FOR_CONSTANTS;
使用此模式时有什么缺点,陷阱或其他注意事项?
答案 0 :(得分:5)
(A)可能很难通过从最终可执行文件中删除不必要的变量来进行优化。
如果要对常量进行分组,请考虑为此使用namespace
。
namespace ConstantGroup
{
constexpr int a = 1;
// Here best solution might depend on usage and c++ version
const std::string b;
}
将常量作为一个组进行传递确实没有多大意义。如果某些内容确实是常量,那么您需要一个定义并始终使用它。
如果常量非常特定于一个类,则将其设为该类的(静态)成员。
答案 1 :(得分:1)
有趣(继与@Henri Menke在上面的评论中有关string
和string_view
s的对话之后。
为此:
#include <string>
#include <string_view>
#include <iostream>
static const std::string a = "a";
static const std::string_view b = "b";
int main ()
{
std::cout << a << "\n";
std::cout << b << "\n";
}
您可以在Godbolt清楚地看到,构造a
需要运行时初始化程序,而b
是编译时常量。
如果您不喜欢阅读编译器生成的代码,请尝试将两个const
更改为constexpr
。然后,std::string_view
仍会编译,而std::string
不会。
因此,对于静态和/或全局常量字符串,constexpr std::string_view = "blah blah blah";
似乎是Henri所说的一个很好的解决方案,因为它在老式的C字符串上提供了相当多的extra functionality ,如果,您可以使用C ++ 17 并且,您无需担心在上下文中将它们转换为std::string
(这将涉及构造一个)的成本那是代码中当时需要的地方。
否则,您将被迫退回到std::string
或普通的旧C字符串。
编辑:
在研究此问题时,我注意到std::stringview
中有一个奇怪的缺点:它不提供operator std::string ()
方法。我不知道为什么不这样做,但是例如,这意味着以下内容不会编译:
void foo (std::string s)
{
...
}
std::string_view sv = ...;
foo (sv);
我说这还不够好,所以本着分享的精神(如果有人还在看这本书),我谨此向您提供:
#include <string>
#include <string_view>
template <class T> struct MyBasicStringView : public std::basic_string_view <T>
{
constexpr MyBasicStringView (const T *s) : std::basic_string_view <T> (s) { }
operator std::basic_string <T> () const { return std::basic_string <T> (this->data ()); }
};
using MyStringView = MyBasicStringView <char>;
测试程序:
static constexpr MyStringView a_static_string_view = "static_string";
std::string foo (std::string s)
{
return s + " x";
}
#include <iostream>
int main ()
{
std::cout << a_static_string_view << "\n";
MyStringView sv = "abcde";
std::cout << sv << "\n";
std::cout << foo (sv) << "\n";
}
输出:
static_string
abcde
abcde x