【发布时间】:2016-03-30 14:34:58
【问题描述】:
我想定义一个函数,当给定一个整数时,它会返回一个字符串。像这样:
# Pseudocode
function get_string(i)
return my_string_array[i]
end
字符串将被硬编码到应用程序中。函数原型在头文件中声明:
// header.h
const std::string &get_string(const int i);
在我看来,我有两个选项来声明硬编码字符串。
选项#1:在get_string中声明一个静态变量
// source.cpp
const std::string &get_string(const int i)
{
static const std::string values[] = {
std::string("foo"),
std::string("bar"),
std::string("baz"),
};
// Assume bounds checking is performed on i.
return values[i];
}
选项 #2:在匿名命名空间中声明全局常量
// source.cpp
namespace
{
const std::string values[] = {
std::string("foo"),
std::string("bar"),
std::string("baz"),
};
}
const std::string &get_string(const int i)
{
// Assume bounds checking is performed on i.
return values[i];
}
对于这个有限的用例,这些声明在功能上是否等效?程序对待函数中的静态常量是否不同于全局声明的常量或匿名命名空间中声明的常量?
我知道明显的可访问性差异(即,在本地命名空间中声明的常量可全局用于同一翻译单元中定义的所有函数),但这可以根据场景的不同方式被认为是一种优势,所以对于这个问题,这个区别可以省略。
【问题讨论】:
-
我能想到的唯一区别是全局变量在程序开始时在输入
main之前被初始化;而函数静态仅在函数第一次调用时才被初始化。在您的情况下,区别可能并不重要。 -
在函数本身内部定义它,如果没有其他人直接使用它(理想情况下没有人应该这样做,否则函数本身就没有用途)。除此之外,在访问元素之前,您必须检查
i的超出范围的值。 -
@Nawaz - 不要害怕,肯定会执行边界检查:-)
-
根据您的用例,如果在编译时知道
i,您可以将get_string设为模板函数,将i作为模板参数并使用模板特化返回适当的字符串.您可能在运行时确定i,所以这可能行不通,只是抛出选项。
标签: c++ static namespaces constants