инициализировать член некоторого класса в списке инициализации, если член является классом шаблона

[Решено]: проблема заключалась не в инициализации класса шаблона, а в специфичной для кода проблеме использования неопределенного макроса внутри конструктора класса шаблона. Ошибка компилятора не жаловалась на неопределенный символ, но была (ошибочно) связана с лямбда-выражениями.

Я искал ответ, но не нашел точного. Ближайший ответ здесь: С++ вызывает явный конструктор шаблонов, но я не уверен, что это полностью связано с моим вопросом. И мой вопрос: как я могу инициализировать член структуры B в списке инициализации, если член является классом шаблона?

Заголовок ClassA.h:

#ifndef _A_
#define _A_
#include <typeinfo>
#include <windows.h>

template<class Type> class A{
        int u,v;
        Type** pointer;
    public:
        A();
        A(int number);
        ~A();
        Type& operator[] (int i){
            typeid(Type);
            return *pointer[i];
        }
        Type& Get(int i)
        {
            typeid(Type);
                return *pointer[i];
        }
        Type *GetPointer(int i) 
        {
            typeid(Type);
                return pointer[i];
        }   
        Type* add ();
        Type& add(Type *element);
        Type& add(Type *element, int place);
        void expand(int NewLength);
        void swap(Type *element, int place);
        void remove(int number);
        void remove(Type *element);
        void removePointer(int number);
        void removePointer(Type *element);
    };
template<class Type>A<Type>::A(){
    u = 128;
    v = 10;
}
template<class Type>A<Type>::A(int number){
            //some thing to do with number;
            u = number;
            v = 10;
            New( pointer, Type *[u] );
        }  
template <class Type> A<Type>::~A()
{
}
template <class Type> void A<Type>::expand(int NewLength)
{

    Type **NewList = NULL;

    NewList = new Type*[NewLength];
}
template <class Type> Type* A<Type>::add ()
{

    pointer[u] = new Type;
}
template <class Type> Type& A<Type>::add(Type *element)
{
}

template <class Type> Type& A<Type>::add(Type *element, int place)
{
}
template <class Type> void A<Type>::swap(Type *element, int place)
{
}
template <class Type> void A<Type>::remove(Type *element)
{
}
template <class Type> void A<Type>::removePointer(int nume)
{
}
template <class Type> void A<Type>::removePointer(Type *element)
{
}
#endif

Заголовок StructB.h:

#pragma once
#ifndef _B_
#define _B_

#include "ClassA.h"
struct C{
    float x,y,z;


};
struct B{
    private:
        B(){
        }
    public:
        int x,y;
        A<B*> member1;
        A<C> member2;

        B(int X,int Y) : member1(5),member2(5) {
            //initialize x,y
        }

        void Add(B* otherB){

            B** _pOtherB = new B*; (*_pOtherB) = otherB;
            member1.add(_pOtherB);

        }

    };

#endif

Компилятор жалуется на эту ошибку (и некоторые другие ошибки, я могу опубликовать их, если нужно):

ошибка C3493: «число» не может быть неявно захвачено, поскольку не указан режим захвата по умолчанию

Есть ли способ сделать это или какой-то обходной путь?

Заранее спасибо


person valdyr    schedule 18.05.2014    source источник
comment
То, что вы разместили, компилируется без ошибок. Пожалуйста, опубликуйте минимальный пример кода, который действительно воспроизводит вашу проблему.   -  person Mat    schedule 18.05.2014
comment
@Mat, хорошо, я отредактирую код   -  person valdyr    schedule 18.05.2014
comment
Сообщение об ошибке, которое вы получили, предназначено только для Lambdas. Вы на сто процентов уверены, что это сообщение об ошибке из приведенного выше кода? В таком случае это ошибка VC++.   -  person Columbo    schedule 18.05.2014
comment
Единственное, что я считаю сомнительным, - это ваш список инициализации для B, в частности, он, вероятно, должен быть : x(X), y(Y), member1(5), и это не вызовет описанного вами состояния ошибки. Частный конструктор для B и пользовательский конструктор по умолчанию для A без списков инициализации совсем имеет гнилостный запах дизайна, но, конечно, не вызовет ошибку, о которой вы сообщаете.   -  person WhozCraig    schedule 18.05.2014
comment
@Arcoth, да, другие ошибки также указывают на то, что они предназначены для лямбда-выражений. Когда я меняю B(int X,int Y) : member1(5) { } на просто B(int X,int Y){ } компилятор не жалуется и компилирует все без ошибок...   -  person valdyr    schedule 18.05.2014
comment
@WhozCraig Я добавил x (X) и y (Y) в список инициализации, но все те же ошибки ... И все ошибки для лямбда-выражений ...   -  person valdyr    schedule 18.05.2014
comment
@valdyr .. и ни в одном из опубликованного вами кода нет лямбдов. Таким образом, ваша проблема не воспроизводится в этом контексте опубликованного кода. Где Type используется в коде, который вы выбрали не для публикации в шаблоне класса A ?   -  person WhozCraig    schedule 18.05.2014
comment
Я разместил более полный код. Проблема в том, что я не могу опубликовать точный код... Существует также структура C, которая используется в качестве аргумента типа для класса шаблона A.   -  person valdyr    schedule 18.05.2014
comment
Попробуйте скомпилировать прямо сейчас! Кажется, это как-то связано с New(указатель, тип *[u]), который находится в конструкторе A(int number). По своей бесконечной глупости я не вижу причины, по которой он не скомпилируется...   -  person valdyr    schedule 18.05.2014
comment
похоже, моя проблема не имеет ничего общего с классом шаблона в списках инициализации, как я думал сначала, а с New(), который находится в A (целое число).   -  person valdyr    schedule 18.05.2014
comment
Чего вы пытаетесь достичь с помощью New(pointer, Type *[u]);?   -  person jhoffman0x    schedule 18.05.2014
comment
@jhoffman0x, ну, код для класса A не мой, но я предполагаю, что он будет выделять память и сохранять указатель на эту память в A::pointer (аналогично этому: pointer = new Type*[u])   -  person valdyr    schedule 18.05.2014


Ответы (1)


Либо код, который вы нам дали, неполный, либо он сломан. Эта строка:

New(pointer, Type *[u]);

кажется, ссылается либо на какой-то отсутствующий метод-член, либо на глобальную функцию, либо просто недействителен. Сообщение об ошибке довольно загадочно, но это C++ для вас.

Я собираюсь предположить, что New является своего рода макросом, потому что ни одна обычная функция (даже шаблонная) не может принимать такое определение типа в качестве параметра. Вы не дали нам определения New, так что мы не можем сказать. Вероятно, отсутствие этого макроса (может быть, оболочка для какой-то системы отладки памяти?) вызывает сумасшедшую ошибку.

Если я заменю строку New на это:

pointer = new Type*[u];

код компилируется нормально.

person Rook    schedule 18.05.2014
comment
да, я также обнаружил проблему с этой строкой... Проблема в том, что я не могу найти объявление New() во всем проекте, но компилятор не жаловался на неопределенный метод/функцию, вместо этого он указал некоторые другая ошибка (а именно ошибки, связанные с labda...) - person valdyr; 18.05.2014
comment
Это цена, которую вы платите за использование языка, грамматика которого немного... неразрешима. В любом случае, New должен быть макросом. Возможно, человек, от которого вы унаследовали код, определил макрос где-то в своей конфигурации VS, а не в своем коде или проекте, или, возможно, у вас просто неполный код. - person Rook; 18.05.2014
comment
Еще более загадочным является тот факт, что я начал пустой новый проект в VS и использовал только код, размещенный в моем вопросе, и все же компилятор жалуется на лямбда-ошибки, а не потому, что New() не определен... - person valdyr; 18.05.2014
comment
Да, я тоже думаю, что это макрос... Мой вопрос следует удалить, чтобы избежать путаницы. - person valdyr; 18.05.2014
comment
Нет, всегда хорошо оставлять вещи в качестве предупреждения другим людям ;-) - person Rook; 18.05.2014
comment
Кстати, компиляция под GCC также выдает некоторые предупреждения о перехвате лямбда, но также выдает error: ‘New’ was not declared in this scope. Таким образом, плохое сообщение об ошибках является частично проблемой C++ и частично проблемой Visual Studio. - person Rook; 18.05.2014
comment
Я также протестировал код в Visual Studio 2008 (который не поддерживает лямбда-выражения), он дает более правильную ошибку. Я думаю, что плохой отчет об ошибках для этого случая связан с Visual Studio 2012. Спасибо за проверку в GCC... - person valdyr; 18.05.2014