#c #floating-point #int
#c #с плавающей запятой #int
Вопрос:
Отсюда у меня смешанные чувства, что что-то не так.
Правда ли, что named int не является значением lvalue, а named float ?
Ответ №1:
В комментарии в ссылке говорится: «Параметры шаблона integer, pointer и member pointer не являются значениями lvalues» (курсив мой). В нем не говорится, что именованные целочисленные переменные не являются значениями lvalues — они есть.
Если бы существовала такая вещь, как параметры шаблона с плавающей запятой, то они также не были бы lvalues ; но именованные переменные с плавающей запятой все равно были бы.
Ответ №2:
Это конкретно связано с использованием int в качестве параметра шаблона, являющегося значением rvalue, в то время как вы не можете использовать числа с плавающей запятой в качестве аргументов шаблона.
например.
template <int T>
struct foo
{
void f(intamp;);
void f(intamp;amp;);
void bar()
{
int x;
f(x); // calls first version
f(T); // calls second version, despite being "named"
}
};
template <float F> // compile error: can't use a float as a template parameter
struct bad {};
Ответ №3:
Что вы подразумеваете под «именованным значением»? В C такой концепции нет. Переменная (независимо от ее типа) является значением lvalue (при использовании в выражении). В большинстве случаев вещи со ссылочными типами являются значениями lvalues, вещи, отличные от переменных с типами данных, — нет (но я уверен, что кто-нибудь найдет некоторые исключения); опять же, тип данных (целое число или с плавающей запятой) не имеет к этому никакого отношения.
В рассматриваемом потоке обсуждаются параметры шаблона, не относящиеся к типу. Приведенное выше правило применяется и здесь: ссылки являются значениями lvalues, другие типы не являются значениями lvalues. Путаница, по-видимому, возникает из-за того, что в качестве параметров шаблона, отличных от типа, может использоваться только очень ограниченный набор не-ссылочных типов: в частности, целочисленные типы в порядке, а типы с плавающей запятой — нет. Таким образом, в шаблоне аргумент с плавающей запятой должен быть ссылкой (и, следовательно, значением lvalue), целочисленный тип может быть либо типом значения (не значением lvalue), либо ссылкой (значением lvalue), например:
template <int N>
struct A { /* N is not an lvalue */ };
template<intamp; N>
struct B { /* N is an lvalue */ };
template <double N>
struct C {}; // This is illegal, and shouldn't compile
template <doubleamp; N>
struct D { /* N is an lvalue */ };
Разница здесь не в том, имеет ли он N
интегральный тип или нет; N
это
ссылка или нет.