Объясните ошибку компиляции
От: MTD https://github.com/mtrempoltsev
Дата: 22.01.18 13:28
Оценка:
Коллеги, объясните пожалуйста почему не компилируется и как забороть:

struct A
{
    static constexpr int foo() { return 1; }
};

template <class T>
void bar(T&& t)
{
    T::foo(); // <-- error
}

int main()
{
    const A a;
    bar(a);
    return 0;
}


1.cpp: In instantiation of ‘void bar(T&&) [with T = const A&]’:
1.cpp:15:10:   required from here
1.cpp:9:11: error: ‘foo’ is not a member of ‘const A&’
     T::foo();
Re: Объясните ошибку компиляции
От: so5team https://stiffstream.com
Дата: 22.01.18 13:31
Оценка: 6 (2)
Здравствуйте, MTD, Вы писали:

MTD>Коллеги, объясните пожалуйста почему не компилируется и как забороть:


https://wandbox.org/permlink/9SzqCmgyfRl9fMom -- например, так.
Re: Объясните ошибку компиляции
От: Constructor  
Дата: 22.01.18 13:36
Оценка: 6 (2)
Здравствуйте, MTD, Вы писали:

MTD>Коллеги, объясните пожалуйста почему не компилируется и как забороть:


MTD>
MTD>1.cpp: In instantiation of ‘void bar(T&&) [with T = const A&]’:
MTD>


T = const A&, т.е. надо избавиться от ссылки и квалификатора const, чтобы получить "голый" тип A. Например, с помощью std::decay<T>::type или std::decay_t<T>.
Re[2]: Объясните ошибку компиляции
От: MTD https://github.com/mtrempoltsev
Дата: 22.01.18 13:41
Оценка:
Здравствуйте, Constructor, Вы писали:

C>T = const A&, т.е. надо избавиться от ссылки и квалификатора const, чтобы получить "голый" тип A.


Спасибо, непонятно только почему если есть константность, то компилятор статический метод не видит
Re: Объясните ошибку компиляции
От: rg45 СССР  
Дата: 22.01.18 13:43
Оценка: 2 (1)
Здравствуйте, MTD, Вы писали:

MTD>Коллеги, объясните пожалуйста почему не компилируется и как забороть:


MTD>
MTD>template <class T>
MTD>void bar(T&& t)
MTD>{
MTD>    T::foo(); // <-- error
MTD>}
MTD>


Все очень просто, T здесь — вовсе не A, как ты ожидаешь, а const A&. Забороть можно по-разному. Например так:

template <class T>
void bar(T&& t)
{
    std::decay_t<T>::foo();
}


или просто вот так:

template <class T>
void bar(const T& t)
{
    T::foo();
}


в зависимости от решаемой задачи.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: Объясните ошибку компиляции
От: MTD https://github.com/mtrempoltsev
Дата: 22.01.18 13:53
Оценка:
Здравствуйте, rg45, Вы писали:

R>Все очень просто, T здесь — вовсе не A, как ты ожидаешь, а const A&. Забороть можно по-разному. Например так:


Это я вижу, мне непонятно почему если A& то статический метод для компилятора есть, а если ссылка константная, то его нет.
Re[2]: Объясните ошибку компиляции
От: T4r4sB Россия  
Дата: 22.01.18 13:55
Оценка:
Здравствуйте, Constructor, Вы писали:

C>T = const A&, т.е. надо избавиться от ссылки и квалификатора const, чтобы получить "голый" тип A. Например, с помощью std::decay<T>::type или std::decay_t<T>.


Оффтоп: для нормального писания на крестах (нормального — это при котором есть смысл выбирать кресты, а не шарпик) вот всю эту хренатень знать обязательно?
Re[3]: Объясните ошибку компиляции
От: rg45 СССР  
Дата: 22.01.18 13:56
Оценка: +1
Здравствуйте, MTD, Вы писали:


C>>T = const A&, т.е. надо избавиться от ссылки и квалификатора const, чтобы получить "голый" тип A.

MTD>Спасибо, непонятно только почему если есть константность, то компилятор статический метод не видит

Он не видит статический метод не потому, что этот тип константный, а потому, что этот тип — ссылка. Вот так тоже будет работать, в этом конкретном случае:

template <class T>
void bar(T&& t)
{
    std::remove_reference_t<T>::foo();
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 22.01.2018 13:56 rg45 . Предыдущая версия .
Re[3]: Объясните ошибку компиляции
От: rg45 СССР  
Дата: 22.01.18 14:00
Оценка: 4 (1)
Здравствуйте, MTD, Вы писали:

MTD>Это я вижу, мне непонятно почему если A& то статический метод для компилятора есть, а если ссылка константная, то его нет.


С неконстантной ссылкой не работает так же, как и с константной: https://ideone.com/yHgA2Z
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: Объясните ошибку компиляции
От: rg45 СССР  
Дата: 22.01.18 14:15
Оценка: +3 -1
Здравствуйте, T4r4sB, Вы писали:

C>>T = const A&, т.е. надо избавиться от ссылки и квалификатора const, чтобы получить "голый" тип A. Например, с помощью std::decay<T>::type или std::decay_t<T>.


TB>Оффтоп: для нормального писания на крестах (нормального — это при котором есть смысл выбирать кресты, а не шарпик) вот всю эту хренатень знать обязательно?


Эта хренотень называется Forwarding References. Не знаю кому как, а мне этой фичи очень не хватало в C++03. Мое мнение — да, обязательно.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: Объясните ошибку компиляции
От: landerhigh Пират  
Дата: 23.01.18 15:30
Оценка: +1
Здравствуйте, T4r4sB, Вы писали:

TB>Оффтоп: для нормального писания на крестах (нормального — это при котором есть смысл выбирать кресты, а не шарпик) вот всю эту хренатень знать обязательно?


ИМХО: она сама тебя узнает, если прижмет именно что писать нормально на плюсах. Хочешь не хочешь, а придется вкурить.
www.blinnov.com
Re: Объясните ошибку компиляции
От: B0FEE664  
Дата: 23.01.18 22:19
Оценка: 6 (2)
Здравствуйте, MTD, Вы писали:

MTD>Коллеги, объясните пожалуйста почему не компилируется и как забороть:


Почему не компилируется коллеги вам уже объяснили. А теперь фокус.
Я заставлю ошибку исчезнуть:

struct A
{
    static constexpr int foo() { return 1; }
};

template <class T>
void bar(T&& t)
{
    t.foo(); // <-- taaa-daaa 
}

int main()
{
    const A a;
    bar(a);
    return 0;
}


ошибка исчезла.
И каждый день — без права на ошибку...
Re[2]: Объясните ошибку компиляции
От: Qt-Coder  
Дата: 24.01.18 05:10
Оценка: :))
Здравствуйте, B0FEE664, Вы писали:

BFE>ошибка исчезла.

В рот мне ноги, Дэвид Блэйн!
Re[2]: Объясните ошибку компиляции
От: MTD https://github.com/mtrempoltsev
Дата: 24.01.18 09:04
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Почему не компилируется коллеги вам уже объяснили.


Нет, мне до сих пор неясно почему такие правила в С++ и чем они аргументированы, неужели по ссылке на тип компилятор не может понять есть ли у типа статический метод.

BFE>А теперь фокус.


Ага, о том и речь
Re[3]: Объясните ошибку компиляции
От: alexanderfedin США http://alexander-fedin.pixels.com/
Дата: 31.03.18 00:11
Оценка:
Здравствуйте, MTD, Вы писали:
MTD>Нет, мне до сих пор неясно почему такие правила в С++ и чем они аргументированы, неужели по ссылке на тип компилятор не может понять есть ли у типа статический метод.
Потому что это уже другой тип.
Respectfully,
Alexander Fedin.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.