Как показывают многие ответы выше, это прекрасно работает.
android:gravity="center"
Если вы хотите отцентрировать его по вертикали:
android:gravity="center_vertical"
или по горизонтали:
android:gravity="center_horizontal"
Как насчет этого:
struct MyPair : public std::pair < int, std::string >
{
const int& keyInt() { return first; }
void keyInt( const int& keyInt ) { first = keyInt; }
const std::string& valueString() { return second; }
void valueString( const std::string& valueString ) { second = valueString; }
};
Это немного многословно, однако использование этого в вашем коде может облегчить чтение, например:
std::vector < MyPair > listPairs;
std::vector < MyPair >::iterator iterPair( listPairs.begin() );
if ( iterPair->keyInt() == 123 )
iterPair->valueString( "hello" );
Кроме этого, я не могу увидеть любую серебряную пулю, которая сделает все намного яснее.
std :: pair
- хороший способ создать «локальный» и по существу анонимный тип с анонимными столбцами; если вы используете определенную пару на таком большом лексическом пространстве, что вам нужно назвать тип и столбцы, я бы вместо этого использовал простую структуру
.
typedef std::pair<bool, int> IsPresent_Value;
typedef std::pair<double, int> Price_Quantity;
... вы поняли.
Как упоминал Алекс, std :: pair
очень удобен, но когда возникает путаница, создайте структуру и используйте ее таким же образом, взгляните на код std :: pair
, это не так уж и сложно.
Мне не нравится std :: pair, используемый в std :: map либо, записи карты должны иметь ключ и значение членов.
Я даже использовал boost :: MIC, чтобы избежать этого. Однако boost :: MIC также имеет свою стоимость.
Кроме того, возвращение std :: pair приводит к менее читаемому коду:
if (cntnr.insert(newEntry).second) { ... }
???
Я также обнаружил, что std :: pair обычно используется ленивыми программистами, которым нужно было 2 значения, но они не думали, зачем эти значения нужны вместе.
Вы можете использовать ускоряющие кортежи, но они на самом деле не меняют основную проблему: действительно ли ваш хочет получить доступ к каждой части пары / кортежа с небольшим интегралом типа, или вам нужен более "грамотный" код. См. этот вопрос Я опубликовал некоторое время назад.
Однако boost :: optional - полезный инструмент, который, как я обнаружил, заменяет довольно много случаев, когда пары / кортежи рекламируются как ответ.
Недавно я обнаружил, что использую boost :: tuple
в качестве замены для std :: pair
. Вы можете определить счетчики для каждого члена, и поэтому очевидно, что каждый член:
typedef boost::tuple<int, int> KeyValueTuple;
enum {
KEY
, VALUE
};
void foo (KeyValueTuple & p) {
p.get<KEY> () = 0;
p.get<VALUE> () = 0;
}
void bar (int key, int value)
{
foo (boost:tie (key, value));
}
Кстати, комментарии приветствуются, если есть скрытая стоимость использования этого подхода.
РЕДАКТИРОВАТЬ: Удалить имена из глобальной области.
Просто быстрый комментарий относительно глобального пространства имен. В общем, я бы использовал:
struct KeyValueTraits
{
typedef boost::tuple<int, int> Type;
enum {
KEY
, VALUE
};
};
void foo (KeyValueTuple::Type & p) {
p.get<KeyValueTuple::KEY> () = 0;
p.get<KeyValueTuple::VALUE> () = 0;
}
Похоже, что boost :: fusion
действительно связывает идентичность и значение ближе друг к другу.
You can create two pairs of getters (const and non) that will merely return a reference to first and second, but will be much more readable. For instance:
string& GetField(pair& p) { return p.first; }
int& GetValue(pair& p) { return p.second; }
Will let you get the field and value members from a given pair without having to remember which member holds what.
If you expect to use this a lot, you could also create a macro that will generate those getters for you, given the names and types: MAKE_PAIR_GETTERS(Field, string, Value, int) or so. Making the getters straightforward will probably allow the compiler to optimize them away, so they'll add no overhead at runtime; and using the macro will make it a snap to create those getters for whatever use you make of pairs.