Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Gorillych
14 / 14 / 1
Регистрация: 04.07.2013
Сообщений: 76
#1

Итераторы, как параметры лябда-функций в шаблонном классе - C++

04.07.2013, 23:38. Просмотров 1003. Ответов 14
Метки нет (Все метки)

Доброго здоровья!

Есть такой код (упрощенный вариант для наглядного описания ситуации):
Код
template<typename Type>
struct A
{
    std::function<Type(typename std::vector<Type>::iterator)> f1 =
    [&](typename std::vector<Type>::iterator arg)
    {
        return *arg ; 
    };
};

int main()
{
    std::vector<float> inp={1};
   
    A<float> obj;
    auto a = inp.begin();
    std::cout<<obj.f1(a);
}
Вылетает такая простыня ошибок при компиляции:
Код
g++-4.7    -c -g -std=c++11 -MMD -MP -MF build/Debug/GNU-Linux-x86/main.o.d -o build/Debug/GNU-Linux-x86/main.o main.cpp
main.cpp:38:52: ошибка: несоответствия типа/значения в аргументе 1 в списке параметров шаблона для «template<class _Signature> class std::function»
main.cpp:38:52: ошибка:   ожидался тип, обнаружено «(Type)(std::vector<_RealType>::iterator)»
main.cpp: In constructor «constexpr A<float>::A()»:
main.cpp:36:8: ошибка: invalid user-defined conversion from «<lambda(std::vector<float, std::allocator<float> >::iterator)>» to «int» [-fpermissive]
main.cpp:39:49: замечание: candidate is: <lambda(std::vector<float, std::allocator<float> >::iterator)>::operator double (*)(std::vector<float, std::allocator<float> >::iterator)() const <near match>
main.cpp:39:49: замечание:   no known conversion for implicit «this» parameter from «double (*)(std::vector<float, std::allocator<float> >::iterator) {aka double (*)(__gnu_cxx::__normal_iterator<float*, std::vector<float, std::allocator<float> > >)}» to «int»
main.cpp: В функции «int main()»:
main.cpp:53:14: замечание: synthesized method «constexpr A<float>::A()» first required here 
main.cpp:54:14: ошибка: нет декларации «inp» в этой области видимости
main.cpp:54:24: ошибка: unable to deduce «auto» from «<expression error>»
main.cpp:55:24: ошибка: «obj.A<float>::f1» нельзя использовать как функцию
Если не делать struct A шаблонной и, соответственно, заменить Type конкретно на float, то все норм. Подскажите, как сдесь правильно заюзать шаблоны?

Заранее спасибо.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.07.2013, 23:38     Итераторы, как параметры лябда-функций в шаблонном классе
Посмотрите здесь:

Параметры в шаблонном классе - C++
Почему в шаблонном классе при описании функции надо два раза указывать тип параметра? В 1-ой строчке есть T и во 2-ой тоже написано T ...

Как вы шаблонном классе определить контейнер, тип которого совпадает с именем параметра шаблона? - C++
собсно template &lt;class T&gt; class perestanovki { public: T&lt;int&gt; v; }; int main () {

Ошибка в шаблонном классе - C++
Помогите исправить ошибку в 12 строчке: error C2248: CMyClass&lt;T&gt;::m_value: невозможно обратиться к private член, объявленному в классе...

String в шаблонном классе - C++
Как сделать так, чтобы в Map&lt;int, std::string&gt; A; работало со string'ом С интами чарами и т.д. все хорошо работает, а на string прога...

Инициализация переменной в шаблонном классе - C++
Как правильно инициализировать шаблонную переменную в классе? Т.е. есть ли какая разница между x() и x( T() ) ? 1-й вариант ...

Работа с матрицей в шаблонном классе - C++
Часть работы разобрал, не получается сделать такое задание как: создать метод который дает возможность изменять кол-во строк или столбцов...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт CЭксперт С++
13052 / 7315 / 814
Регистрация: 27.09.2012
Сообщений: 18,052
Записей в блоге: 3
Завершенные тесты: 1
04.07.2013, 23:43     Итераторы, как параметры лябда-функций в шаблонном классе #2
Вы инициализируете переменную прямо в объявлении класса.
Попробуйте так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
template<typename Type>
struct A
{
    std::function<Type(typename std::vector<Type>::iterator)> f1;
    A(){
         f1 =
    [&](typename std::vector<Type>::iterator arg)
    {
        return *arg ; 
    };
     }
};
Jupiter
Каратель
Эксперт С++
6553 / 3973 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
04.07.2013, 23:49     Итераторы, как параметры лябда-функций в шаблонном классе #3
Gorillych, и какой по-твоему контекст ([&]) должен быть захвачен по ссылке?
ssXXss
264 / 186 / 10
Регистрация: 15.01.2011
Сообщений: 668
05.07.2013, 00:17     Итераторы, как параметры лябда-функций в шаблонном классе #4
можно еще чутка сократить :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template<typename Type, typename R >
struct A
{
    std::function<R(typename Type::iterator)> f1;
    A(){
        f1 = [&]( Type::iterator arg)
        {
            return *arg ; 
        };
    }
};
//
    std::vector<float> inp (10);
    A<std::vector<float>,float> obj;
    auto a = inp.begin();
    auto d = obj.f1(a);
Gorillych
14 / 14 / 1
Регистрация: 04.07.2013
Сообщений: 76
05.07.2013, 00:58  [ТС]     Итераторы, как параметры лябда-функций в шаблонном классе #5
Croessmah, ssXXss, спасибо за ответы, Ваши варианты работают, но...
Давайте усложним задачу:

BaseClass.hpp:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef BASECLASS_HPP
#define BASECLASS_HPP
 
template<typename Type> 
class BaseClass
{
public:
    BaseClass(unsigned int NumelemsInVector);
    virtual void action();
    
    std::function<void(std::vector<Type>::iterator)> f;
    std::vector<Type> v;    
};
 
template<typename Type>
BaseClass<Type>::BaseClass(unsigned int NumelemsInVector) : v(NumelemsInVector)
{
    f = [&](std::vector<Type>::iterator arg){*arg += 1;};
}
 
template<typename Type>
void BaseClass<Type>::action()
{
    //Do nothing
}
 
#endif  /* BASECLASS_HPP */

DerClass.hpp:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#ifndef DERCLASS_HPP
#define DERCLASS_HPP
 
#include "BaseClass.hpp"
 
template<typename Type> 
class DerClass : BaseClass<Type>
{
public:
    DerClass(unsigned int NumelemsInVector);
    virtual void action() override;
};
 
template<typename Type>
DerClass<Type>::DerClass(unsigned int NumelemsInVector) : BaseClass<Type>(NumelemsInVector)
{
    
}
 
template<typename Type>
void DerClass<Type>::action()
{
    auto CurrentElement = this->v.begin(); 
    for(unsigned int i=0; i<this->v.size(); ++i)
    {
        this->f(CurrentElement);
        CurrentElement++;
    }
}
#endif  /* DERCLASS_HPP */
main.cpp:
C++
1
2
3
4
5
6
#include "DerClass.hpp"
int main()
{
   DerClass<float> obj(5);
   obj.action();
}
Теперь ошибки:
Код
In file included from DerClass.hpp:4:0,
                 from main.cpp:10:
BaseClass.hpp:11:52: ошибка: несоответствия типа/значения в аргументе 1 в списке параметров шаблона для «template<class _Signature> class std::function»
BaseClass.hpp:11:52: ошибка:   ожидался тип, обнаружено «(void)(std::vector<_RealType>::iterator)»
BaseClass.hpp: In constructor «BaseClass<Type>::BaseClass(unsigned int)»:
BaseClass.hpp:18:38: ошибка: «std::vector<_RealType, std::allocator<_Tp1> >::iterator» is not a type
BaseClass.hpp: In lambda function:
BaseClass.hpp:18:53: ошибка: invalid type argument of unary «*» (have «int»)
DerClass.hpp: In instantiation of «void DerClass<Type>::action() [with Type = float]»:
In file included from main.cpp:10:0:
main.cpp:44:16:   required from here
DerClass.hpp:26:9: ошибка: «((DerClass<float>*)this)->DerClass<float>::<anonymous>.BaseClass<float>::f» нельзя использовать как функцию
BaseClass.hpp: In instantiation of «BaseClass<Type>::BaseClass(unsigned int) [with Type = float]»:
In file included from DerClass.hpp:4:0,
                 from main.cpp:10:
DerClass.hpp:15:91:   required from «DerClass<Type>::DerClass(unsigned int) [with Type = float]»
main.cpp:43:26:   required from here
BaseClass.hpp:18:5: ошибка: invalid user-defined conversion from «BaseClass<Type>::BaseClass(unsigned int) [with Type = float]::<lambda(int)>» to «int» [-fpermissive]
BaseClass.hpp:18:50: замечание: candidate is: BaseClass<Type>::BaseClass(unsigned int) [with Type = float]::<lambda(int)>::operator void (*)(int)() const <near match>
BaseClass.hpp:18:50: замечание:   no known conversion for implicit «this» parameter from «void (*)(int)» to «int»
P.S. Сразу хочу попросить не обращать внимания на тело метода action в DerClass - это просто для наглядности написано.

Добавлено через 1 минуту
Цитата Сообщение от Jupiter Посмотреть сообщение
Gorillych, и какой по-твоему контекст ([&]) должен быть захвачен по ссылке?
В общем-то, никакого контекста здесь нет - хоть [&], хоть [=] - без разницы. Можно и не лямбду даже.
Croessmah
Модератор
Эксперт CЭксперт С++
13052 / 7315 / 814
Регистрация: 27.09.2012
Сообщений: 18,052
Записей в блоге: 3
Завершенные тесты: 1
05.07.2013, 01:02     Итераторы, как параметры лябда-функций в шаблонном классе #6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
template<typename Type> 
class BaseClass
{
public:
    BaseClass(unsigned int NumelemsInVector);
    virtual void action();
    
    std::function<void(typename std::vector<Type>::iterator)> f;//тут typename std::vector<Type>::iterator
    std::vector<Type> v;    
};
 
template<typename Type>
BaseClass<Type>::BaseClass(unsigned int NumelemsInVector) : v(NumelemsInVector)
{
    f = [&](typename std::vector<Type>::iterator arg){*arg += 1;};//И тут typename std::vector<Type>::iterator
}
 
template<typename Type>
void BaseClass<Type>::action()
{
    //Do nothing
}
typename'ы забыли

Добавлено через 1 минуту

Не по теме:

Цитата Сообщение от Gorillych Посмотреть сообщение
хоть [&], хоть [=]
а можно и пустыми оставить

Gorillych
14 / 14 / 1
Регистрация: 04.07.2013
Сообщений: 76
05.07.2013, 01:08  [ТС]     Итераторы, как параметры лябда-функций в шаблонном классе #7
Croessmah, да, все заработало) Большое спасибо за помощь)
А Вы не могли бы буквально в двух словах объяснить зачем нужны были typename'ы в этих местах? Честно говоря, я еще не до конца разобрался с этими тайпнеймами )
Croessmah
Модератор
Эксперт CЭксперт С++
13052 / 7315 / 814
Регистрация: 27.09.2012
Сообщений: 18,052
Записей в блоге: 3
Завершенные тесты: 1
05.07.2013, 01:10     Итераторы, как параметры лябда-функций в шаблонном классе #8
Цитата Сообщение от Gorillych Посмотреть сообщение
А Вы не могли бы буквально в двух словах объяснить зачем нужны были typename'ы в этих местах?
чтобы указать, что iterator - это имя типа. Вообще, для типов, которые зависят от параметров шаблона лучше указывать typename, хотя в некоторых моментах компилятор сможет и сам разобраться
Gorillych
14 / 14 / 1
Регистрация: 04.07.2013
Сообщений: 76
05.07.2013, 01:12  [ТС]     Итераторы, как параметры лябда-функций в шаблонном классе #9
Цитата Сообщение от Croessmah Посмотреть сообщение
чтобы указать, что iterator - это имя типа. Вообще, для типов, которые зависят от параметров шаблона лучше указывать typename, хотя в некоторых моментах компилятор сможет и сам разобраться
Все понял) Еще раз спасибо)
Jupiter
Каратель
Эксперт С++
6553 / 3973 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
05.07.2013, 01:27     Итераторы, как параметры лябда-функций в шаблонном классе #10
IMHO
Цитата Сообщение от Gorillych Посмотреть сообщение
В общем-то, никакого контекста здесь нет
лямбда на то лябда чтобы быть в контексте...остается долько гадать что двигало разрабами нового синтаксического сахара
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct B;
 
struct A
{
    A(B*);
};
 
struct B
{
   A* a = new A(this);
};
 
A::A(B*)
{
    
}
 
int main()
{    
}
http://ideone.com/bhSrG9
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
partial class B
{
    
}
 
class A
{
   public A(B b)
   {
       
   }
}
 
partial class B
{
    A a = new A(this);
}
 
class Program
{
    static void Main()
    {
        
    }
}
http://ideone.com/g4DAUv
и на этом понимании - в каком контексте лямбда можно мозг сломать.
это не укладывается в рамки "простого и понятного кода"
ssXXss
264 / 186 / 10
Регистрация: 15.01.2011
Сообщений: 668
05.07.2013, 02:09     Итераторы, как параметры лябда-функций в шаблонном классе #11
но жизнь лямбда малость упростила ) к примеру :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
int i = 900;
    int r = 555;
    int y = 800;
 
    std::thread th([&]()
    {
        int x = i + r + y;
        for(int a = 0; a < x; a++)
        {
            i += a;
        }
    });
    th.join();
...
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
05.07.2013, 14:41     Итераторы, как параметры лябда-функций в шаблонном классе #12
Jupiter, Вцелом, так, да. Однако, не забываем, что инициализация в классе эквивалентна инициализации в конструкторе.

Коды по сути эквивалентны.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class B;
 
class A
{
public:
   A(B*);
};
 
class B
{
public:
   A* a = new A(this);
};
 
A::A(B*) {}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class B;
 
class A
{
public:
   A(B*);
};
 
class B
{
public:
   B() : a(new A(this))
   {
   }
   A* a;
};
 
A::A(B*) {}
И если помнить это, то все прекрасно и понятно.
svk2140
-8 / 0 / 1
Регистрация: 04.07.2013
Сообщений: 263
05.07.2013, 14:54     Итераторы, как параметры лябда-функций в шаблонном классе #13
в следующий раз используй
C++
1
using namespace std;
не придётся каждый раз писать std::
Croessmah
Модератор
Эксперт CЭксперт С++
13052 / 7315 / 814
Регистрация: 27.09.2012
Сообщений: 18,052
Записей в блоге: 3
Завершенные тесты: 1
05.07.2013, 15:09     Итераторы, как параметры лябда-функций в шаблонном классе #14
svk2140, Этой фразой Вы подписали себе смертный приговор, сейчас налетят коршуны, в т.ч. и я

Если Вам это так нравится, то используйте, но не навязывайте свое мнение другим, ибо для многих using namespace std; является бредом, от которого одни проблемы я в числе сторонников явного указания пространства имен!

Да и вообще, судя по тому, что для Вас это лишь "не придется писать std", возникает вопрос - Вы вообще знаете что Вы делаете using'ом?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.07.2013, 15:13     Итераторы, как параметры лябда-функций в шаблонном классе
Еще ссылки по теме:

typedef в шаблонном классе фыв - C++
Есть некий шаблонный класс с typedef'ом, и функция которая возвращает тип описанный typedef: ... template&lt;class T&gt; class Blablabla...

Найти ошибки в шаблонном классе - C++
Пишу шаблонный класс в Qt, и, конечно же, на моих любимых шаблонах не обошлось без проблем :(. Структура кода стандартная - *.h + *.cpp. В...

Конструктор копирования в шаблонном классе - C++
//Header.h #include &lt;iostream&gt; #include &lt;conio.h&gt; #define NULL 0 template &lt;typename T&gt; class Laser { ...

Статическая функция в шаблонном классе - C++
Под windows все отлично работало, но под linux выдает ошибку : /home/stalker/Рабочий стол/H-Array/Homework_Array/Array.h:121: ошибка:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Gorillych
14 / 14 / 1
Регистрация: 04.07.2013
Сообщений: 76
05.07.2013, 15:13  [ТС]     Итераторы, как параметры лябда-функций в шаблонном классе #15
Цитата Сообщение от svk2140 Посмотреть сообщение
в следующий раз используй
C++
1
using namespace std;
не придётся каждый раз писать std::
Спасибо за совет, не знал, что так можно делать
Yandex
Объявления
05.07.2013, 15:13     Итераторы, как параметры лябда-функций в шаблонном классе
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru