Проблемы с передачей анонимной временной функции-объекта в шаблонизированный конструктор - PullRequest
3 голосов
/ 06 апреля 2010

Я пытаюсь прикрепить функцию-объект, который будет вызываться при уничтожении шаблонного класса. Тем не менее, я не могу передать функцию-объект как временную. Я получаю предупреждение (если комментарий строка xi.data = 5;):

    warning C4930: 'X<T> xi2(writer (__cdecl *)(void))': 
    prototyped function not called (was a variable definition intended?)
            with
            [
                T=int
            ]

и если я пытаюсь использовать построенный объект, я получаю сообщение об ошибке компиляции:

error C2228: left of '.data' must have class/struct/union

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

template<typename T>
struct Base
{
    virtual void run( T& ){}
    virtual ~Base(){}
};

template<typename T, typename D>
struct Derived : public Base<T>
{
    virtual void run( T& t )
    {
        D d;
        d(t);
    }
};

template<typename T>
struct X
{
    template<typename R>
    X(const R& r)
    {
       std::cout << "X(R)" << std::endl;
       ptr = new Derived<T,R>(); 
    }

    X():ptr(0)
    { 
        std::cout << "X()" << std::endl; 
    }

    ~X()
    {
        if(ptr) 
        {
            ptr->run(data);
            delete ptr;
        }
        else
        {
            std::cout << "no ptr" << std::endl;
        }
    }

    Base<T>* ptr; 
    T data;
};

struct writer
{
    template<typename T>
    void operator()( const T& i )
    { 
        std::cout << "T : " << i << std::endl;
    }
};

int main()
{
    {
        writer w;
        X<int> xi2(w);
        //X<int> xi2(writer()); //This does not work!
        xi2.data = 15;       
    }

    return 0;
};

Причина, по которой я пытаюсь это сделать, заключается в том, что я «каким-то образом» могу связывать типы объектов-функций с объектами, не сохраняя экземпляр самого объекта-функции внутри класса. Таким образом, когда я создаю объект class X, мне не нужно держать в нем объект class writer, а только указатель на Base<T> (я не уверен, нужен ли здесь <T>, но сейчас его там).

Проблема в том, что мне кажется, что мне нужно создать объект writer и затем передать его конструктору X, а не вызывать его как X<int> xi(writer();

Возможно, мне не хватает чего-то совершенно глупого и очевидного, какие-либо предложения?

Ответы [ 3 ]

7 голосов
/ 06 апреля 2010

Похоже, "самый неприятный анализ" проблема. Попробуйте

X<int> xi2 = X<int>(writer());

или

X<int> xi2((writer()));
5 голосов
/ 06 апреля 2010

X<int> xi2(writer()); - это объявление функции с именем xi2, которая сама возвращает X<int> и принимает в качестве параметра функцию, которая не принимает параметров и возвращает записывающее устройство. Это «самый неприятный анализ».

Решение - сделать то, что вы сделали, избегая временных, или добавить дополнительные скобки.

5 голосов
/ 06 апреля 2010

Попробуйте дополнительную пару скобок вокруг X<int> xi2((writer())); Это остановит компилятор, думая, что вы предварительно называете функцию. (Scott Meyers Effective STL Item 6.)

...