Используя статическую переменную наряду с шаблонами

После обширных исследований, проб и ошибок и беседы с командой поддержки Heroku я узнал, что, хотя ответ Медленного Лориса был частью процесса, следующий ответ был предоставлен мне службой Heroku:

< blockquote>

Чтобы сократить длинную историю, местный геройку официально не поддерживается для приложений PHP>. Причина в том, что в отличие от всех других языков, которые мы поддерживаем на платформе>, PHP не имеет веб-серверов, написанных в userland. Вместо этого мы используем PHP-FPM> вместе с Apache или Nginx, а сценарии загрузки (vendor / bin / heroku- (php | hhvm) - (apache2 | nginx)) динамически вставляют правильную конфигурацию для привязки порта> и сообщения FastCGI сокеты.

Это работает с ванильными PHP и сборками Apache при условии, что:

1) у текущего пользователя есть все правильные разрешения (в вашем случае> / var / log / apache2 / не доступен для записи); 2) правильные прокси-модули загружаются в главный httpd.conf; 3) главный httpd.conf не привязывается к порту вообще или, по крайней мере, не к одному> под 1024 (который зарезервирован для суперпользователей).

Основная конфигурация также должна обрабатываться каждый пользователь сам по себе, потому что> иногда модули, которые нужно загрузить, находятся в libexec /, иногда в> lib / apache2 / modules / и т. д. Просто слишком много вариаций; в противном случае мы могли бы> отправить полную конфигурацию Apache для пользователей, и опыт был бы намного лучше.

Но проблемы на этом не заканчиваются. FPM вообще не работает в Windows и на> большинстве Linux-систем, httpd не является командой, которая работает; вместо этого apache2ctl> обрабатывает запуск и остановку, и, таким образом, запуск сервера на переднем плане невозможен. В конце концов, существует просто слишком много возможных перестановок в> системных конфигурациях, которые делают невозможным гарантировать, что каждый пользователь обладает отличным опытом.

Это просто текущая реальность на земле PHP. Ruby, Python, Node, Java имеют все> веб-серверы, которые написаны на каждом соответствующем языке, и вам не нужны внешние серверы. Это также позволяет передавать потоки файлов, обрабатывать web> обновления сокетов и т. Д. Возможно, с PHP 7 мы увидим что-то вроде этого> emerge soon (в PHP 5 это просто невозможно, потому что фатальная ошибка> убивает движок, поэтому ваш веб-сервер тоже исчезнет).

18
задан EvilTeach 3 March 2009 в 17:15
поделиться

3 ответа

Вы получаете две копии той же переменной, потому что Вы объявили статическую переменную в заголовочном файле. Когда Вы объявляете глобальную переменную static этот путь, Вы говорите, что это локально для единицы компиляции (.o файл). Так как Вы включаете заголовок в две единицы компиляции, Вы получаете две копии count.

я думаю, что Вы действительно хотите, вот статическая шаблонная членская переменная, связанная с каждым экземпляр из шаблонного класса. Это было бы похоже на это:

template <class T>
class MyClass
{
    // static member declaration
    static int count;
    ...
};

// static member definition
template<class T> int MyClass<T>::count = 0;

Это получит Вас счет для каждого инстанцирования Вашего шаблона. Таким образом, у Вас будет счет MyClass<int>, MyClass<foo>, MyClass<bar>, и т.д. f1() был бы теперь похож на это:

void f1() {
    MyClass<int> a;
    a.f();

    cout<<"F1: " << MyClass<int>::count <<"\n";
}
<час>

, Если Вы хотите счет весь инстанцирования MyClass (независимо от их шаблонных параметров), действительно необходимо использовать глобальная переменная .

Однако Вы, вероятно, не хотите глобальной переменной непосредственно, потому что Вы рискуете использовать ее, прежде чем она будет инициализирована. Можно обойти это путем создания глобального статического метода, который возвращает ссылку на количество:

int& my_count() {
    static int count = 0;
    return count;
}

Тогда доступ к нему из Вашего класса как это:

void f() {
    ++my_count();
}

Это гарантирует, что количество инициализируется, прежде чем оно будет использоваться, независимо от которой единицы компиляции Вы получаете доступ к нему от. Посмотрите FAQ C++ на статическом порядке инициализации на большее количество деталей.

23
ответ дан 30 November 2019 в 08:27
поделиться

Помещение статического объявления в заголовочном файле заставит каждый .cpp файл получать свою собственную версию переменной. Таким образом, два оператора суда печатают различные переменные.

3
ответ дан 30 November 2019 в 08:27
поделиться

Вы ожидали "F1:1 Main:1"? Вы инстанцировали MyClass<int> в двух отдельных единицах перевода (т.е. двух объектных файлах), и компоновщик видел, что было дублирующееся шаблонное инстанцирование, таким образом, оно отбросило инстанцирование, которое было в f1 объектный файл.

Вы передающий /OPT:ICF или /OPT:REF компоновщику VC6? Это могло бы быть связано с дублирующимся шаблонным удалением инстанцирования (или нет; дублирующиеся шаблонные инстанцирования могли бы быть особым случаем, по сравнению с обычными дублирующимися функциями). GCC, кажется, делает что-то подобное на некоторых платформах.

Так или иначе, я не полагался бы на это поведение, являющееся последовательным через компиляторы. Кроме того, изменение порядка объектных файлов на командной строке компоновщика могло бы влиять, какое инстанцирование отбрасывается.

1
ответ дан 30 November 2019 в 08:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: