1

Тема: Не працює шаблон

Вітаю.

Є невеличка проблемка. Хто зможе конкретно пояснити то прошу.
Трошки про себе, щоб розуміти мій рівень підготовки.

Чому функція працює, а шаблон ні?
Тобто в опису немає помилок, а в виклику, якщо шаблон то помилка.

Функція:

inline const std::vector<std::string> getvector(const std::vector<std::string>::const_iterator& B, const std::vector<std::string>::const_iterator& E) {
    std::vector<std::string> A{};
    if (B < E) {
        auto C{ B };
        while (C != E) {
            A.push_back(*(C++));
        }
    }
    return A;
}

Шаблон:

template<typename Type>
inline const  std::vector<Type> getvector(const typename std::vector<Type>::const_iterator& B, const typename std::vector<Type>::const_iterator& E) {
    std::vector<Type> A{};
    if (B < E) {
        auto C{ B };
        while (C != E) {
            A.push_back(*(C++));
        }
    }
    return A;
}

Виклик:

return getvector(m_array[Block][Group].cbegin() + 1, m_array[Block][Group].cend());

Дякую за увагу.

2

Re: Не працює шаблон

getvector<std::string>(....)

C++ не настільки розумний, що б з const typename std::vector<std::string>::const_iterator задедьюсити, що треба саме getvector<std::string> інстанціювати.

Подякували: Spiriter1

3

Re: Не працює шаблон

Тип T у виразі const typename std::vector<Type>::const_iterator не може бути виведений, бо цей контекст є non-deducible. В основному, все, що знаходиться зліва від :: (scope resolution operator), не виводиться (якщо :: відокремлює вкладене ім’я).

N4659/17.8.2.5 Deducing template arguments from a type написав:

In most cases, the types, templates, and non-type values that are used to compose P participate in template
argument deduction. That is, they may be used to determine the value of a template argument, and the
value so determined must be consistent with the values determined elsewhere. In certain contexts, however,
the value does not participate in type deduction, but instead uses the values of template arguments that were
either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts
and is not explicitly specified, template argument deduction fails.

N4659/17.8.2.5 Deducing template arguments from a type написав:

The non-deduced contexts are:
— The nested-name-specifier of a type that was specified using a qualified-id.

Вся проблема у тому, що бувають кейси, коли компілятор напевне не зможе вивести тип, взагалі, і опиниться в неоднозначній ситуації. Наприклад, через спеціалізацію.

koala написав:

C++ не настільки розумний

Відчувається оця нотка зневаги )
Переїжджаємо на раст?)

Подякували: koala, leofun01, Spiriter, sensei4

4

Re: Не працює шаблон

Якщо ті хто мають більший досвід кажуть однозначно, що це неможливо, то буду вважати що це так.
Хоча зрозуміло, що це не костиль мови, а недоробка компіляторів. Поки що їхній AI більше схожий на IA як в того ослика.
Дякую всім хто відповів.

5 Востаннє редагувалося koala (21.01.2020 21:37:25)

Re: Не працює шаблон

Що саме, вибачте, неможливо? Ви ж не написали, що саме хотіли отримати.
Ні, звісно, якщо вам треба, щоб саме цей код працював - то це дійсно неможливо, вибачте, у мови є свої правила.
А якщо вам, наприклад, треба, щоб можна було викликати функцію getvector, ніби це не шаблон, то

template<typename Iterator>
inline const  std::vector<typename std::iterator_traits<Iterator>::value_type> 
                                                                  getvector(const Iterator& B, const Iterator& E) {
    std::vector<typename std::iterator_traits<Iterator>::value_type> A{};
    if (B < E) {
        auto C{ B };
        while (C != E) {
            A.push_back(*(C++));
        }
    }
    return A;
}
Подякували: Spiriter, leofun01, sensei3

6 Востаннє редагувалося wander (21.01.2020 22:21:47)

Re: Не працює шаблон

Spiriter написав:

Якщо ті хто мають більший досвід кажуть однозначно, що це неможливо, то буду вважати що це так.

Так говорите наче, нам послугу робите, повіривши у неможливе. Зараз є модним вислів не вірити нікому, та провіряти все самому, загалом, у даному випадку можете ним скористатися, якщо раптом ви вважаєте інакше. Зрештою, для цього я дав вам вирізки з діючого стандарту мови (з посиланнями на конкретні глави), то ж ви вже знаєте де шукати.

Spiriter написав:

Хоча зрозуміло, що це не костиль мови, а недоробка компіляторів. Поки що їхній AI більше схожий на IA як в того ослика.

В компіляторах немає ніякого АІ і так, це не костиль мови. Якщо правилами мови визначаються конкретні положення та поведінки, як от вихід за межі масиву, чи спроба вивести ім'я з non-deducible контексту, то це не означає, що у цьому винен компілятор, чи, що це костиль мови. Просто інакше, якщо це дозволити, то це поламає вашу програму, та/або поламає інші, вже існуючі можливості мови, чи змусить ускладнювати й так не простий синтаксис мови, що майже завжди тягне за собою ускладнення для розробників компіляторів. У вашому випадку все доволі просто:

template <typename T>
struct dummy_t {
    using type = T;
};

template <>
struct dummy_t<int> {
    using type = double;
};

template <typename T>
void foo(typename dummy_t<T>::type const&) noexcept {}

int main() {
    double d;
    foo(d); // який `T` тут має вивести компілятор?
}

В даному випадку підходять обидва кандидати: dummy_t<double> та dummy_t<int> будуть мати тип double, як вложений.

Подякували: Spiriter, leofun012

7

Re: Не працює шаблон

Там є ШІ. Тепер зусиллями маркетологів під ШІ чомусь розуміють майже виключно нейронні мережі; насправді ж навіть комп'ютерна арифметика - це ШІ, причому це та галузь ШІ, де ми досягли найбільших успіхів. Процес компіляції - безумовно інтелектуальна робота, я не певен, що цьому можна навчити навіть шимпанзе. Так, це строго формалізована інтелектуальна робота, що дозволяє її автоматизувати, але це таки ШІ.
А от розпізнавання зображень якраз інтелекту не потребує - комах ніби поки що ніхто не запідозрив у особливих інтелектуальних здібностях, а розпізнавати вони вміють.

Подякували: Spiriter, ReAl, leofun013

8

Re: Не працює шаблон

koala і adziri не кіпішуйте обидва )) Я ж подякував.
Але то не справжні програмери якщо вони просто заспокоїлись і лягли спати. Мабуть ви ще в школу ходили коли я думи думав і шукав рішення проблем без інтернету. Я ж не дарма про себе хоч троки написав.
І все ж таки воно працює. Просто треба було підказати компілятору тип повернення.
Виклик:

return getvector<std::string>(m_array[Block][Group].cbegin() + 1, m_array[Block][Group].cend());

Рішення koala теж працює і навіть краще, без підказок компілятору. В принципі це те що і було потрібно.
Ще раз дякую.

Подякували: leofun011

9

Re: Не працює шаблон

Насправді я школу в 1998-му закінчив, так що ви молодші за мене з adziri разом.

І все ж постарайтеся формулювати питання з трьох частин:
- завдання (що треба зробити);
- що ви зробили (код);
- що вийшло (не "не працює", а точний опис того, що відбулося насправді).

Мені це дуже допомагає - 60% моїх питань закінчуються (я розумію відповідь) після повного формулювання завдання, а в цілому це одразу дає відповідь на 90%.

10

Re: Не працює шаблон

koala написав:

Насправді я школу в 1998-му закінчив, так що ви молодші за мене з adziri разом.

давайте не будемо, бо

я вже не стримався і пишу, що коли у мене був «обчислювальний практикум» на Алголі на М4030-1, мови С++ ще не існувало.

Подякували: 0xDADA11C7, koala, leofun01, Spiriter4

11

Re: Не працює шаблон

koala написав:

А от розпізнавання зображень якраз інтелекту не потребує - комах ніби поки що ніхто не запідозрив у особливих інтелектуальних здібностях, а розпізнавати вони вміють.

Отож. Хоча нейронів у її нейронці немало. Але це, якщо брати інші аналогії, «жорстка» логіка, а не мікропроцесор.
Цю нейронку «вчили» тисячоліття еволюції, але ШІ це їй не додало.

Подякували: leofun01, Spiriter2

12

Re: Не працює шаблон

koala написав:

Насправді я школу в 1998-му закінчив, так що ви молодші за мене з adziri разом.

Років на 10 таки ви молодше, але це не погано ж. ;)

13

Re: Не працює шаблон

Spiriter написав:
koala написав:

Насправді я школу в 1998-му закінчив, так що ви молодші за мене з adziri разом.

Років на 10 таки ви молодше, але це не погано ж. ;)

А разом ми старші :)

14

Re: Не працює шаблон

koala написав:

А разом ми старші

Якщо мій вік докинути до життєвого досвіду пана Коали, то може навіть доженемо пана ReAl :D

15

Re: Не працює шаблон

Все ж таки дивно, чому компіляторщикам складно це реалізувати.
Бо отака штучка працює нормально і більше універсальна:

template<typename Type>
inline void fill(
    const typename Type::const_iterator& B,
    const typename Type::const_iterator& E,
    Type& O) {
    if (B < E) {
        auto C{ B };
        while (C != E) {
            O.push_back(*(C++));
        }
    }
}

Може і зі строками з char-ами працювати і з векторами з різними типами. Ну що є.
Вважаючи що років через 15 допілили тип byte офіційно, то тут хоч є нюанси.

16 Востаннє редагувалося wander (22.01.2020 17:51:43)

Re: Не працює шаблон

Spiriter написав:

Бо отака штучка працює нормально і більше універсальна:

Вона по факту майже така ж, як і в 1му пості)

Може і зі строками з char-ами працювати

Не може, бо до char-ів не застосовується оператор ::, бо це фундаментальний тип.
Більше того ваш fill буде конкурувати з ф-ю зі стандартної бібліотеки з якої ви схоже, чесно скопіювали параметри ))

17 Востаннє редагувалося koala (22.01.2020 17:52:53)

Re: Не працює шаблон

Spiriter написав:

Все ж таки дивно, чому компіляторщикам складно це реалізувати.

Мабуть, тому ж, чому вам важко написати завдання. Хоча ні, не тому. Річ у тім, що C++ об'єднує купу різних парадигм, причому ще й додає до кожної якісь штучки, щоб обійти це, на кшталт const_cast, щоб обійти чи friend, щоб обійти обмеження доступу. А в результаті треба продумувати, як реагувати на ситуації, де треба автоматично визначати, константу передадуть в лямбду в шаблоні чи не константу. Звісно, дещо при цьому йде не зовсім добре. Хочеться, щоб усе було гладенько? Беріть Rust. Там, щоправда, задля цієї розумності заборона на забороні, зате заборонені переважно "погані" речі.

Spiriter написав:

Бо отака штучка працює нормально і більше універсальна:

Це ж треба, ви придумали стандартний метод insert! Щоправда, стандартний insert може і з множинами, і в довільне місце, і з різними типами джерела і цілі, але то вже таке.

adziri написав:

Не може, бо до char-ів не застосовується оператор ::, бо це фундаментальний тип.

А тепер Type - це контейнер, а не елемент.

adziri написав:

Більше того ваш fill буде конкурувати з ф-ю зі стандартної бібліотеки з якої ви схоже, чесно скопіювали параметри ))

Тільки працює з точністю до навпаки.

18

Re: Не працює шаблон

koala написав:

А тепер Type - це контейнер, а не елемент.

Даєте таку гарантію?)

19

Re: Не працює шаблон

adziri написав:
koala написав:

А тепер Type - це контейнер, а не елемент.

Даєте таку гарантію?)

Звісно, ні, це ж C++. Визначить свій неконтейнерний тип з підтипом const_iterator - і поламаєте все, що можна, включно з STL.

Подякували: leofun011

20 Востаннє редагувалося wander (22.01.2020 18:02:40)

Re: Не працює шаблон

koala написав:

поламаєте все, що можна, включно з STL

Тільки стандартний std::fill спокійно працює і з не контейнерними типами.

koala написав:

Тільки працює з точністю до навпаки.

Знач тре перейменувати в reverse_fill :)