Предположим, у меня есть исходный файл A.cpp:
#include<string>
struct A {
static const std::string a;
static const std::string b;
static const std::string c;
};
const std::string A::a{"1"};
const std::string A::b{"2"};
const std::string A::c{"3"};
И хотите использовать A::b
в другой единице перевода. Обычный способ - это разделить A.cpp
на объявление A.hpp
и определение, включая первое.
#include<iostream>
#include<A.hpp>
int main(){
std::cout << A::b << "\n";
return 0;
}
Это, безусловно, сработает, но я хочу не включать объявление класса, потому что в моем случае A
огромен и имеет громоздкие зависимости.
В идеале я хочу что-то вроде
struct A;
external const std::string A::m;
Но это приводит к ошибке неполного типа.
Можно полагаться на ссылки через другие не классовые глобальные переменные.
const std::string A::b{"2"};
const std::string* bptr{&A::b};
и объявить его в другом исходном файле как
extern const std::string* bptr;
Это правильный путь, но выглядит для меня немного уродливо, потому что требует введения избыточной сущности.
Еще один трюк, который работает для меня.
struct A {
static const std::string b;
};
int main(){
std::cout << A::b << "\n";
return 0;
}
Выглядит хорошо, но хакерски, работает даже для частных пользователей. Это законно? То есть, есть что-нибудь, что определяет такое поведение?