Перед
const char * const g_someString = "Hello";
вам нужно объявить его как extern
(например, путем включения в заголовок), поскольку переменные уровня const
пространства имен имеют внутреннюю связь по умолчанию.
Сказанное: вы можете просто определить строки в заголовке. Отдельная компиляция покупает вам возможность изменять строки без возникновения перебора большого количества файлов, но кроме того, IMHO - это преждевременная оптимизация.
Для определения строк в заголовке формально безопасного для inline
функций, если это необходимо, вам нужны строки (или хотя бы указатели), чтобы иметь extern
связи. Один из способов сделать это - использовать специальное исключение для шаблонов в правиле одного определения. Например. как это:
// Perhaps best generated by some code generation facility:
template< class Dummy >
struct Strings_
{
static char const* const some_string;
static char const* const some_other_string;
};
template< class Dummy >
char const* const Strings_<Dummy>::some_string = "Blah!";
template< class Dummy >
char const* const Strings_<Dummy>::some_string = "Oh, well.";
using Strings = Strings_<void>;
Тогда использование как
inline void foo() { cout << Strings::some_string << endl; }
Здесь Strings::some_string
указатель будет одинаковым во всех единицах трансляции.
Альтернативой является определение строк в пределах функции inline
. Затем вы можете использовать, например. перечисление, чтобы назвать их.
enum String_id { some_string, some_other_string };
inline
auto strings(String_id const id)
-> char const*
{
switch(id)
{
case some_string: return "Blah!";
case some_other_string: return "Oh, well.";
}
assert(false); // Should never get here.
}
с использованием как
inline void foo() { cout << strings(some_string) << endl; }
inline
extern
функция имеет связи, и таким образом это то же самое во всех единицах трансляции.
Ошибка компоновщика исчезает с объявлением _extern_ перед определением в _constants.cpp_ – Karthik
убедитесь, что 'constants.cpp' включает' constants.h' (и у вас нет круговых зависимостей) –
'void main' is незаконно в C++, даже если ваш компилятор предлагает неконфигурирующее расширение, нехорошо писать код, который полагается на такие расширения. –