Другим совершенно другим способом является точка монтирования в uwsgi
.
Из документа doc about Хостинг нескольких приложений в одном и том же процессе ( permalink ).
В вашем uwsgi.ini
вы добавляете
[uwsgi]
mount = /foo=main.py
manage-script-name = true
# also stuff which is not relevant for this, but included for completeness sake:
module = main
callable = app
socket = /tmp/uwsgi.sock
Если вы не вызываете свой файл main.py
, вам необходимо изменить оба mount
и module
Ваш main.py
может выглядеть так:
from flask import Flask, url_for
app = Flask(__name__)
@app.route('/bar')
def bar():
return "The URL for this page is {}".format(url_for('bar'))
# end def
И конфигурация nginx (опять же для полноты):
server {
listen 80;
server_name example.com
location /foo {
include uwsgi_params;
uwsgi_pass unix:///temp/uwsgi.sock;
}
}
Теперь вызов example.com/foo/bar
отобразит /foo/bar
, как возвращено флягой url_for('bar')
, так как оно автоматически адаптируется. Таким образом, ваши ссылки будут работать без проблем с префиксами.
Как указано, код на самом деле разрабатывают число элементов в массиве, не структуру. Я просто выписал бы sizeof () подразделение явно, когда я хочу это. Если бы я должен был сделать это функцией, то я хотел бы прояснить в ее определении, что это ожидает массив.
template<typename T,int SIZE>
inline size_t array_size(const T (&array)[SIZE])
{
return SIZE;
}
Вышеупомянутое подобно xtofl's, кроме него принимает меры против передачи указателя на него (который говорит что точка динамично выделенному массиву), и получение неправильного ответа по ошибке.
Править: Упрощенный согласно JohnMcG. Править: встроенный.
К сожалению, вышеупомянутое не предоставляет ответ времени компиляции (даже если компилятор действительно встраивает и оптимизирует его, чтобы быть константой под капотом), так не может использоваться в качестве константного выражения времени компиляции. т.е. Это не может использоваться в качестве размера для объявления статического массива. Под C++ 0x, уходит эта проблема, если Вы заменяете ключевое слово, встроенное constexpr (constexpr, встроено неявно).
constexpr size_t array_size(const T (&array)[SIZE])
решение jwfearn работает в течение времени компиляции, но включает наличие определения типа, которое эффективно "сохранило" размер массива в объявлении нового имени. Размер массива затем разработан путем инициализации константы через то новое имя. В таком случае можно также просто сохранить размер массива в константу от запуска.
Отправленное решение Martin York также работает под временем компиляции, но включает использование нестандартного typeof () оператор. Работа вокруг к этому, любой ожидают C++ 0x и используют decltype (которым временем нельзя было бы на самом деле быть нужен он для этой проблемы, поскольку у нас будет constexpr). Другая альтернатива должна использовать Повышение. Typeof, в этом случае мы закончим с
#include <boost/typeof/typeof.hpp>
template<typename T>
struct ArraySize
{
private: static T x;
public: enum { size = sizeof(T)/sizeof(*x)};
};
template<typename T>
struct ArraySize<T*> {};
и используется путем записи
ArraySize<BOOST_TYPEOF(foo)>::size
где нечто является названием массива.
Для массивов переменной длины C99-стиля кажется, что чистый макро-подход (sizeof (прибытие) / sizeof (прибытие [0])) является единственным, который будет работать.
Конкретный Windows:
Существует макрос _countof()
предоставленный CRT точно с этой целью.
Отвеченный подробно здесь: Часть 1 определения Размера Массива и здесь: Часть 2 определения Размера Массива.
Как ответ JohnMcG, но
Недостаток - Вы, будет иметь копию этого в Вашем двоичном файле для каждого Имени типа, комбинации Размера.
Вот почему Вы сделали бы это встроенной шаблонной функцией.
xtofl имеет правильный ответ для нахождения размера массива. Никакой макрос или шаблон не должны быть необходимыми для нахождения размера структуры, так как sizeof () должен сделать приятно.
Я соглашаюсь, что препроцессор является злым, но существуют случаи, где это является наименее злым из альтернатив.
Я предпочитаю перечислимый метод, предложенный [BCS] (в этом макросе, может быть преобразован в функцию?)
Это вызвано тем, что можно использовать его, где компилятор ожидает постоянное время компиляции. Текущая версия языка не позволяет Вам использовать результаты функций за время компиляции consts, но я верю этому прибытию в следующую версию компилятора:
Проблема с этим методом состоит в том, что он не генерирует ошибку времени компиляции при использовании с классом, который перегрузился '*' оператор (см. код ниже для деталей).
К сожалению, версия, предоставленная 'BCS', действительно не совсем компилирует как ожидалось, таким образом, вот моя версия:
#include <iterator>
#include <algorithm>
#include <iostream>
template<typename T>
struct StructSize
{
private: static T x;
public: enum { size = sizeof(T)/sizeof(*x)};
};
template<typename T>
struct StructSize<T*>
{
/* Can only guarantee 1 item (maybe we should even disallow this situation) */
//public: enum { size = 1};
};
struct X
{
int operator *();
};
int main(int argc,char* argv[])
{
int data[] = {1,2,3,4,5,6,7,8};
int copy[ StructSize<typeof(data)>::size];
std::copy(&data[0],&data[StructSize<typeof(data)>::size],©[0]);
std::copy(©[0],©[StructSize<typeof(copy)>::size],std::ostream_iterator<int>(std::cout,","));
/*
* For extra points we should make the following cause the compiler to generate an error message */
X bad1;
X bad2[StructSize<typeof(bad1)>::size];
}
Да это может быть сделано шаблоном в C++
template <typename T>
size_t getTypeSize()
{
return sizeof(T)/sizeof(*T);
}
использовать:
struct JibbaJabba
{
int int1;
float f;
};
int main()
{
cout << "sizeof JibbaJabba is " << getTypeSize<JibbaJabba>() << std::endl;
return 0;
}
См. сообщение BCS выше или ниже о прохладном способе сделать это с классом во время компиляции с помощью некоторого легкого шаблонного метапрограммирования.
Я не думаю, что это действительно разрабатывает число элементов в структуре. Если структура упаковывается, и Вы использовали вещи, меньшие, чем размер указателя (такие как символ в 32-разрядной системе) затем, Ваши результаты являются неправильными. Кроме того, если структура содержит структуру, Вы неправы также!
@KTC Simplfying, так как у нас есть размер массива в аргументе шаблона:
template<typename T, int SIZE>
int arraySize(const T(&arr)[SIZE])
{
return SIZE;
}
Недостаток - Вы, будет иметь копию этого в Вашем двоичном файле для каждого Имени типа, комбинации Размера.
Тип шаблонной функции выведен автоматически, в отличие от типа шаблонного класса. Можно использовать его еще более простой:
template< typename T > size_t structsize( const T& t ) {
return sizeof( t ) / sizeof( *t );
}
int ints[] = { 1,2,3 };
assert( structsize( ints ) == 3 );
Но я соглашаюсь, что это не работает на структуры: это работает на массивы. Таким образом, я назвал бы это Arraysize :)
Ваш макрос неверно называется, это нужно назвать ARRAYSIZE. Это используется для определения числа элементов в массиве, кто размер, фиксируется во время компиляции. Вот способ, которым это может работать:
символьное нечто [128];//В действительности, у Вас было бы некоторое константное или константное выражение как размер массива.
для (неподписанный я = 0; я <STRUCTSIZE (нечто); ++ i) {}
Это является довольно хрупким для использования, потому что можно сделать эту ошибку:
символ* нечто = новый символ [128];
для (неподписанный я = 0; я <STRUCTSIZE (нечто); ++ i) {}
Вы теперь выполните итерации, поскольку я = 0 к <1 и отрываю Ваши волосы.
Макрос имеет очень вводящее в заблуждение имя - выражение в макросе возвратит число элементов в массиве, если имя массива будет передано в как макро-параметр.
Для других типов Вы получите что-то более или менее бессмысленное, если тип будет указателем, или Вы получите синтаксическую ошибку.
Обычно тот макрос называют чем-то как NUM_ELEMENTS () или чем-то для указания на его истинную полноценность. Не возможно заменить макрос функцией в C, но в C++ может использоваться шаблон.
Версия, которую я использую, основана на коде в winnt.h заголовке Microsoft (сообщает мне, если регистрация этого отрывка идет вне добросовестного использования):
//
// Return the number of elements in a statically sized array.
// DWORD Buffer[100];
// RTL_NUMBER_OF(Buffer) == 100
// This is also popularly known as: NUMBER_OF, ARRSIZE, _countof, NELEM, etc.
//
#define RTL_NUMBER_OF_V1(A) (sizeof(A)/sizeof((A)[0]))
#if defined(__cplusplus) && \
!defined(MIDL_PASS) && \
!defined(RC_INVOKED) && \
!defined(_PREFAST_) && \
(_MSC_FULL_VER >= 13009466) && \
!defined(SORTPP_PASS)
//
// RtlpNumberOf is a function that takes a reference to an array of N Ts.
//
// typedef T array_of_T[N];
// typedef array_of_T &reference_to_array_of_T;
//
// RtlpNumberOf returns a pointer to an array of N chars.
// We could return a reference instead of a pointer but older compilers do not accept that.
//
// typedef char array_of_char[N];
// typedef array_of_char *pointer_to_array_of_char;
//
// sizeof(array_of_char) == N
// sizeof(*pointer_to_array_of_char) == N
//
// pointer_to_array_of_char RtlpNumberOf(reference_to_array_of_T);
//
// We never even call RtlpNumberOf, we just take the size of dereferencing its return type.
// We do not even implement RtlpNumberOf, we just decare it.
//
// Attempts to pass pointers instead of arrays to this macro result in compile time errors.
// That is the point.
//
extern "C++" // templates cannot be declared to have 'C' linkage
template <typename T, size_t N>
char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N];
#define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A)))
//
// This does not work with:
//
// void Foo()
// {
// struct { int x; } y[2];
// RTL_NUMBER_OF_V2(y); // illegal use of anonymous local type in template instantiation
// }
//
// You must instead do:
//
// struct Foo1 { int x; };
//
// void Foo()
// {
// Foo1 y[2];
// RTL_NUMBER_OF_V2(y); // ok
// }
//
// OR
//
// void Foo()
// {
// struct { int x; } y[2];
// RTL_NUMBER_OF_V1(y); // ok
// }
//
// OR
//
// void Foo()
// {
// struct { int x; } y[2];
// _ARRAYSIZE(y); // ok
// }
//
#else
#define RTL_NUMBER_OF_V2(A) RTL_NUMBER_OF_V1(A)
#endif
#ifdef ENABLE_RTL_NUMBER_OF_V2
#define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V2(A)
#else
#define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V1(A)
#endif
//
// ARRAYSIZE is more readable version of RTL_NUMBER_OF_V2, and uses
// it regardless of ENABLE_RTL_NUMBER_OF_V2
//
// _ARRAYSIZE is a version useful for anonymous types
//
#define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)
#define _ARRAYSIZE(A) RTL_NUMBER_OF_V1(A)
Кроме того, книга Matthew Wilson "Имперфект, C++" имеет хорошую обработку того, что продолжается здесь (Раздел 14.3 - страница 211-213 - Массивы и Указатели - dimensionof ()).
Решение KTC является чистым, но оно не может использоваться во время компиляции, и это зависит от компиляторной оптимизации для предотвращения чрезмерного увеличения размера кода и вызова функции наверху.
Можно вычислить размер массива с единственной временем компиляции метафункцией с нулевой стоимостью во время выполнения. BCS был на правильном пути, но то решение является неправильным.
Вот мое решение:
// asize.hpp
template < typename T >
struct asize; // no implementation for all types...
template < typename T, size_t N >
struct asize< T[N] > { // ...except arrays
static const size_t val = N;
};
template< size_t N >
struct count_type { char val[N]; };
template< typename T, size_t N >
count_type< N > count( const T (&)[N] ) {}
#define ASIZE( a ) ( sizeof( count( a ).val ) )
#define ASIZET( A ) ( asize< A >::val )
с тестовым кодом (использующий Повышение. StaticAssert для демонстрации единственного временем компиляции использования):
// asize_test.cpp
#include <boost/static_assert.hpp>
#include "asize.hpp"
#define OLD_ASIZE( a ) ( sizeof( a ) / sizeof( *a ) )
typedef char C;
typedef struct { int i; double d; } S;
typedef C A[42];
typedef S B[42];
typedef C * PA;
typedef S * PB;
int main() {
A a; B b; PA pa; PB pb;
BOOST_STATIC_ASSERT( ASIZET( A ) == 42 );
BOOST_STATIC_ASSERT( ASIZET( B ) == 42 );
BOOST_STATIC_ASSERT( ASIZET( A ) == OLD_ASIZE( a ) );
BOOST_STATIC_ASSERT( ASIZET( B ) == OLD_ASIZE( b ) );
BOOST_STATIC_ASSERT( ASIZE( a ) == OLD_ASIZE( a ) );
BOOST_STATIC_ASSERT( ASIZE( b ) == OLD_ASIZE( b ) );
BOOST_STATIC_ASSERT( OLD_ASIZE( pa ) != 42 ); // logic error: pointer accepted
BOOST_STATIC_ASSERT( OLD_ASIZE( pb ) != 42 ); // logic error: pointer accepted
// BOOST_STATIC_ASSERT( ASIZE( pa ) != 42 ); // compile error: pointer rejected
// BOOST_STATIC_ASSERT( ASIZE( pb ) != 42 ); // compile error: pointer rejected
return 0;
}
Это решение отклоняет нетипы массива во время компиляции, таким образом, оно не запутается указателями, как макро-версия делает.
Ни один до сих пор не предложил портативный способ получить размер массива, когда у Вас только есть экземпляр массива и не его типа. (typeof и _countof не является портативным, так не может использоваться.)
Я сделал бы это следующий путь:
template<int n>
struct char_array_wrapper{
char result[n];
};
template<typename T, int s>
char_array_wrapper<s> the_type_of_the_variable_is_not_an_array(const T (&array)[s]){
}
#define ARRAYSIZE_OF_VAR(v) sizeof(the_type_of_the_variable_is_not_an_array(v).result)
#include <iostream>
using namespace std;
int main(){
int foo[42];
int*bar;
cout<<ARRAYSIZE_OF_VAR(foo)<<endl;
// cout<<ARRAYSIZE_OF_VAR(bar)<<endl; fails
}
Я перенес конструкцию в макрос, чтобы иметь некоторый достойный синтаксис. Если Вы хотите избавиться от него, Ваша единственная опция состоит в том, чтобы сделать замену вручную.
Править: Из кода Doug
template <typename T>
uint32_t StructSize() // This might get inlined to a constant at compile time
{
return sizeof(T)/sizeof(*T);
}
// or to get it at compile time for shure
class StructSize<typename T>
{
enum { result = sizeof(T)/sizeof(*T) };
}
Мне сказали, что 2-й не работает. OTOH что-то как он должно быть осуществимо, я просто, не используют C++ достаточно для фиксации его.
Страница на C++ (и D) обрабатывает по шаблону для материала времени компиляции