Russian Qt Forum
Апрель 30, 2024, 16:01 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Константное выражение в качестве члена класса.  (Прочитано 8368 раз)
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« : Февраль 09, 2017, 10:05 »

Привет, друзья!
Прошу помочь разобраться, почему не работают методы класса, помеченные как constexpr в коде ниже.
Я ожидаю, что вместо вызова метода во время компиляции будет подставлено константное значение.
Код
C++ (Qt)
#include <QSize>
struct MyStruct
{
   int width() const;
   static constexpr QSize size{20, 20};
};
 
 
int MyStruct::width() const
{
   return size.width();
}
 
int main()
{
   MyStruct().width();
   return 0;
}
 
Цитировать
undefined reference to `MyStruct::size'
« Последнее редактирование: Февраль 09, 2017, 13:59 от __Heaven__ » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Февраль 09, 2017, 10:19 »

static зачем?
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #2 : Февраль 09, 2017, 11:06 »

Нельзя константное выражение делать членом класса без использования static.
Записан
panAlexey
Гипер активный житель
*****
Offline Offline

Сообщений: 864

Акцио ЗАРПЛАТА!!!!! :(


Просмотр профиля
« Ответ #3 : Февраль 09, 2017, 11:10 »

Код:
int MyStruct::width() const
{
    return MyStruct::size.width();
}
не?
Записан

Win Xp SP-2, Qt4.3.4/MinGW. http://trdm.1gb.ru/
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #4 : Февраль 09, 2017, 11:35 »

Код:
int MyStruct::width() const
{
    return MyStruct::size.width();
}
не?
не.

Кажется проблема в QSize, но это не точно. Следующий код работает.

Код
C++ (Qt)
class Size {
double w,h;
public:
constexpr Size(double w, double h)
: w(w), h(h){}
 
constexpr double width() const{
return w;
}
 
constexpr double height() const{
return h;
}
};
 
struct MyStruct
{
   int width() const;
   static constexpr Size size{20, 20};
};
 
 
int MyStruct::width() const
{
   return size.width();
}
 
int main(void) {
MyStruct().width();
return 0;
}
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #5 : Февраль 09, 2017, 11:46 »

Немного ошибся насчёт полной работоспособности предыдущего поста.

Попробовал 4 компилятора (clang, gcc, mingw32, mingw64)
Почему-то в gcc подобных код из поста #1 компилится только в release версии. Clang не компилит вообще.
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #6 : Февраль 09, 2017, 12:03 »

Может как-то так надо:

Код
C++ (Qt)
struct MyStruct
{
   int width() const;
   constexpr Size size() const
   { return Size(20, 20); }
};
Записан

Пока сам не сделаешь...
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #7 : Февраль 09, 2017, 12:14 »

Может как-то так надо:

Код
C++ (Qt)
struct MyStruct
{
   int width() const;
   constexpr Size size() const
   { return Size(20, 20); }
};
Грязный хак Улыбающийся но работает)))
Но какого лешего не работает исходное решение??

Кстати, компилер странный код генерирует в отсутствие ключей оптимизации. Он будто игнорирует constexpr. См. аттач.
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #8 : Февраль 09, 2017, 12:48 »

Чего это хак, да ещё и грязный Улыбающийся? Чем MyStruct::size() отличается от Size::width()? Такая же constexpr функция. И если оптимизация не задана пользователем, зачем компилятор будет оптимизировать? Попробуйте следующий код. Без оптимизации и с "-O3", например.

Код
C++ (Qt)
class Size {
double w,h;
public:
constexpr Size(double w, double h)
   : w(w), h(h){}
 
constexpr double width() const{
return w;
}
 
constexpr double height() const{
return h;
}
};
 
struct MyStruct
{
   int width() const;
 
   constexpr Size size() const
   { return Size(20, 20); }
};
 
int MyStruct::width() const
{
return size().width();
}
 
int main(void) {
return MyStruct().width();
}
 
Записан

Пока сам не сделаешь...
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #9 : Февраль 09, 2017, 13:03 »

Чего это хак, да ещё и грязный Улыбающийся?
Да я шучу Улыбающийся Просто я хотел член класса, а вы вжух и метод предложили.

Ну, с -O3 он хорошо жмётся, что весьма предсказуемо.
Код
ASM
MyStruct::width() const:
       mov     eax, 20
       ret
main:
       mov     eax, 20
       ret
 
Кстати, мой код перестаёт компилиться при включении оптимизирующих опций. Видать constexpr это не обязательство, а объявление возможности (как и с inline).
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #10 : Февраль 09, 2017, 13:10 »

Я забыл упомянуть, что за пределами класса константа себя весьма хорошо чувствует - всё штатно.
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #11 : Февраль 09, 2017, 13:15 »

Там, заодно по идее, и MyStruct::width() тоже должно быть constexpr, тогда сожмётся ещё лучше Улыбающийся.
Код
C++ (Qt)
struct MyStruct
{
   constexpr double width() const
   { return size().width(); }
 
   constexpr Size size() const
   { return Size(20, 20); }
};
 
Записан

Пока сам не сделаешь...
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #12 : Февраль 09, 2017, 13:24 »

Дык а некуда дальше))) И так уже просто 20 заносится в регистр и выходит)
Специально не стал делать этот метод constexpr, дабы приблизить пример к тому, что у меня в проекте используется.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #13 : Февраль 09, 2017, 13:31 »

А зацените это вот Улыбающийся Получил в результате издёвок над компилером
Код
C++ (Qt)
class Size {
   double w,h;
public:
   constexpr Size(double w, double h) noexcept
       : w(w), h(h){}
 
   constexpr double width() const noexcept{
       return w;
   }
 
   constexpr double height() const noexcept{
       return h;
   }
};
 
struct MyStruct
{
   constexpr int width() const noexcept;
   static const Size size;
};
constexpr Size MyStruct::size{20, 20};
 
 
constexpr int MyStruct::width() const noexcept
{
   return size.width();
}
 
int main() {
   constexpr int w = MyStruct().width();
   return 0;
}
 

В объявлении MyStruct нет опечатки это всё компилится
« Последнее редактирование: Февраль 09, 2017, 13:33 от __Heaven__ » Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #14 : Февраль 09, 2017, 13:48 »

Да, чем дальше в С++, тем больше дров  Смеющийся. Осталось только не запутаться во всех этих способах инициализации, конструкторах и им подобного ).
Записан

Пока сам не сделаешь...
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.185 секунд. Запросов: 22.