Именованный int против именованного float

#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 это
ссылка или нет.