Вы имеете в виду размер байта или длину строки?
Размер байта измеряется с помощью strlen()
, тогда как длина строки запрашивается с использованием mb_strlen()
. Вы можете использовать substr()
для обрезки строки в X bytes (обратите внимание, что это приведет к поломке строки, если она имеет многобайтовое кодирование - как указано Darhazer в комментариях) и mb_substr()
чтобы обрезать его до X символов в кодировке строки.
Этот ответ должен быть довольно коротким и сладким, чтобы ответить (часть) озаглавленного вопроса. Если вы хотите получить более подробный ответ, объясняющий, почему вы должны их там поместить, пожалуйста, перейдите здесь .
Общее правило для размещения typename
в основном, когда вы используете параметр шаблона, и хотите получить доступ к вложенному typedef
или с использованием псевдонима, например:
template<typename T>
struct test {
using type = T; // no typename required
using underlying_type = typename T::type // typename required
};
Обратите внимание, что это также относится к метафункциям или вещи, которые также принимают общие параметры шаблона. Однако, если предоставленный параметр шаблона является явным типом, вам не нужно указывать typename
, например:
template<typename T>
struct test {
// typename required
using type = typename std::conditional<true, const T&, T&&>::type;
// no typename required
using integer = std::conditional<true, int, float>::type;
};
Общие правила добавления определителя template
в основном аналогичны, за исключением они обычно включают шаблонные функции-члены (статические или другие) структуры / класса, которые сами шаблоны, например:
Учитывая эту структуру и функцию:
template<typename T>
struct test {
template<typename U>
void get() const {
std::cout << "get\n";
}
};
template<typename T>
void func(const test<T>& t) {
t.get<int>(); // error
}
Попытка доступа t.get<int>()
изнутри функции приведет к ошибке:
main.cpp:13:11: error: expected primary-expression before 'int'
t.get<int>();
^
main.cpp:13:11: error: expected ';' before 'int'
Таким образом, в этом контексте вам понадобится ключевое слово template
заранее и вызвать его так:
t.template get<int>()
Таким образом, компилятор будет анализировать это правильно, а не t.get < int
.
typedef typename Tail::inUnion<U> dummy;
Однако я не уверен, что реализация inUnion верна. Если я правильно понимаю, этот класс не должен быть создан, поэтому вкладка «fail» никогда не будет автоматически терпеть неудачу. Возможно, было бы лучше указать, находится ли тип в объединении или нет с простым булевым значением.
template <typename T, typename TypeList> struct Contains;
template <typename T, typename Head, typename Tail>
struct Contains<T, UnionNode<Head, Tail> >
{
enum { result = Contains<T, Tail>::result };
};
template <typename T, typename Tail>
struct Contains<T, UnionNode<T, Tail> >
{
enum { result = true };
};
template <typename T>
struct Contains<T, void>
{
enum { result = false };
};
PS: Посмотрите на Boost :: Variant
PS2: посмотрите на typelists , особенно в книге Андрея Александреску: Modern C ++ Design