Невозможно ограничить типы шаблонов, но вы можете определить разные действия на основе типа. В качестве части общего числового пакета мне понадобился общий класс для добавления двух значений.
class Something<TCell>
{
internal static TCell Sum(TCell first, TCell second)
{
if (typeof(TCell) == typeof(int))
return (TCell)((object)(((int)((object)first)) + ((int)((object)second))));
if (typeof(TCell) == typeof(double))
return (TCell)((object)(((double)((object)first)) + ((double)((object)second))));
return second;
}
}
Обратите внимание, что типыof оцениваются во время компиляции, поэтому операторы if будут удалены компилятором. Компилятор также удаляет ложные нажатия. Итак, что-то разрешило в компиляторе
internal static int Sum(int first, int second)
{
return first + second;
}
Они эквивалентны, даже если вы отключите оптимизатор.
Пример:
#include <stdio.h>
extern void f(void) {
while(1) {
putchar(' ');
}
}
extern void g(void) {
for(;;){
putchar(' ');
}
}
extern void h(void) {
z:
putchar(' ');
goto z;
}
Компиляция с помощью gcc -O0
дает эквивалентную сборку для всех 3 функций:
f:
; [ EXTERNAL ]
;
+00000 00000fb4 80402DE9 stmdb sp!,{r7,lr}
+00004 00000fb8 00708DE2 add r7,sp,#0x0
+00008 00000fbc 2000A0E3 loc_000008: mov r0,#0x20
+0000c 00000fc0 0A0000EB bl putchar (stub)
+00010 00000fc4 FCFFFFEA b loc_000008
;
;
g:
; [ EXTERNAL ]
;
+00000 00000fc8 80402DE9 stmdb sp!,{r7,lr}
+00004 00000fcc 00708DE2 add r7,sp,#0x0
+00008 00000fd0 2000A0E3 loc_000008: mov r0,#0x20
+0000c 00000fd4 050000EB bl putchar (stub)
+00010 00000fd8 FCFFFFEA b loc_000008
;
;
h:
; [ EXTERNAL ]
;
+00000 00000fdc 80402DE9 stmdb sp!,{r7,lr}
+00004 00000fe0 00708DE2 add r7,sp,#0x0
+00008 00000fe4 2000A0E3 loc_000008: mov r0,#0x20
+0000c 00000fe8 000000EB bl putchar (stub)
+00010 00000fec FCFFFFEA b loc_000008
while(1)
и for(;;)
в точности эквивалентны, и оба являются хорошо понятными идиомами для кодирования бесконечных циклов.
Я бы избегал использования goto
: чтобы выйти из бесконечного цикла или перейти к следующей итерации, используйте break
и continue
.
Хотя нет существенной разницы, как упоминалось в других статьях, общая причина использования for (;;)
вместо while (1)
состоит в том, что инструменты статического анализа (и некоторые компиляторы с определенными уровнями предупреждений) часто жалуются на цикл while. 114]
Goto немного неприятен, но должен генерировать тот же код, что и остальные. Лично я придерживаюсь for (;;)
(чтобы Линт был доволен), но у меня нет проблем с while (1)
.
Из того, что я помню о моих "разборочных годах", это не будет иметь большого значения (компиляторы достаточно умны ). Это больше об эстетике ИМО.
Я бы серьезно предложил использовать Python для такого аппликатина. Это снимет бремя декодирования полосок (не говоря уже о выделении памяти для них и тому подобного). Вы сможете сосредоточиться на своей проблеме, а не на языковых проблемах.
Например, если приведенное выше предложение содержится в файле utf-8 и используется файл python2.x. Если вы используете python 3 .x это еще более читаемо, так как вам не нужно префиксировать строки Юникода с 'u "', как в этом примере (но вы будете пропускать много сторонних библиотек:
separators = [u"।", u",", u"."]
text = open("indiantext.txt").read()
#This converts the encoded text to an internal unicode object, where
# all characters are properly recognized as an entity:
text = text.decode("utf-8")
#this breaks the text on the white spaces, yielding a list of words:
words = text.split()
counter = 1
output = ""
for word in words:
#if the last char is a separator, and is joined to the word:
if word[-1] in separators and len(word) > 1:
#word up to the second to last char:
output += word[:-1] + u"(%d) " % counter
counter += 1
#last char
output += word[-1] + u"(%d) " % counter
else:
output += word + u"(%d) " % counter
counter += 1
print output
Это" развернутый "пример, как вы больше привыкли к Python есть более короткие способы выразить это. Вы можете изучить основы языка за пару часов, следуя учебному пособию. (например, сама http://python.org )
-121--3791878-См. эту ссылку, чтобы имитировать вызов getJSON в методах установки/разрыва, http://www.ajaxprojects.com/ajax/tutorialdetails.php?itemid=505
-121--1277132-Я только что сравнил неоптимизированные выходные данные ассемблера gcc:
# cat while.c
int main() {
while(1) {};
return 0;
}
# cat forloop.c
int main() {
for (;;) { };
return 0;
}
Make assembler output:
# gcc -S while.c
# gcc -S forloop.c
Compare assembler files:
# diff forloop.s while.s
1c1
< .file "forloop.c"
---
> .file "while.c"
Поскольку вы видите, что существенных различий нет. Вот результат
# cat while.s
.file "while.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
.L2:
jmp .L2 # this is the loop in both cases
.size main, .-main
.ident "GCC: (GNU) 4.4.3"
.section .note.GNU-stack,"",@progbits
Хотя это не является техническим доказательством того, что они одинаковы, я бы сказал, что это в 99,9% случаев.
Практически нет никакой разницы в сгенерированной сборке. Это скорее стилистическая проблема:
Goto - просто ooogly: прыжок назад, без явного бесконечного блока
while (1) - лучше, требует "фиктивного" условия, и вы будете часто предупреждение компилятора (уровень предупреждения 4) или инструмент статического анализа
для (;;) может быть не самым красивым, но imho подходит лучше всего, потому что эта конструкция не может иметь никакого другого значения (по сравнению с while). Но некоторые другие люди предпочитают while (1) по "той же" причине ...
Нет. Используйте то, что наиболее читабельно для вас
В C истина
реализуется следующим образом (в зависимости от компилятора)
#define TRUE 1
или
#define TRUE (-1)
И ложь реализуется как
#define FALSE 0
, поэтому while (1)
эквивалентно while (true)
, поскольку 0 считается ложным.
while (1) == для (;;)
, поскольку нет условия остановки.
, который переводится на ассемблер как
:loop
...
...
...
goto loop
, поэтому, если в коде ассемблера нет инструкции ret
или exit
, это считается бесконечным циклом.