Если вас интересуют только 8-битные символы (что допускают и все другие ответы, кроме Милана Бабушкова), вы можете добиться максимальной скорости, создав таблицу соответствия во время компиляции с использованием метапрограммирования. На ideone.com он работает в 7 раз быстрее, чем библиотечная функция, и в 3 раза быстрее, чем рукописная версия (http://ideone.com/sb1Rup).. Его также можно настраивать с помощью признаков без замедления.
template<int ...Is>
struct IntVector{
using Type = IntVector<Is...>;
};
template<typename T_Vector, int I_New>
struct PushFront;
template<int ...Is, int I_New>
struct PushFront<IntVector<Is...>,I_New> : IntVector<I_New,Is...>{};
template<int I_Size, typename T_Vector = IntVector<>>
struct Iota : Iota< I_Size-1, typename PushFront<T_Vector,I_Size-1>::Type> {};
template<typename T_Vector>
struct Iota<0,T_Vector> : T_Vector{};
template<char C_In>
struct ToUpperTraits {
enum { value = (C_In >= 'a' && C_In <='z') ? C_In - ('a'-'A'):C_In };
};
template<typename T>
struct TableToUpper;
template<int ...Is>
struct TableToUpper<IntVector<Is...>>{
static char at(const char in){
static const char table[] = {ToUpperTraits<Is>::value...};
return table[in];
}
};
int tableToUpper(const char c){
using Table = TableToUpper<typename Iota<256>::Type>;
return Table::at(c);
}
с вариантом использования:
std::transform(in.begin(),in.end(),out.begin(),tableToUpper);
Для более детального (многостраничного) описания того, как это работает, позвольте мне бесстыдно подключить мой блог: http://metaporky.blogspot.de/2014/07/part-4-generating-look-up-tables-at.html