Как определить функцию-член шаблонного класса, которая возвращает объект вложенного класса

template<typename IPC_TYPE>
class Poller
{
private:

public:
    struct Event
    {
        std::shared_ptr<IPC> ipc;
        enum Status
        {
            NONE = 0, POLLIN = 1, POLLHUP = 2, MessageArrival = 3
        }status;
    };

    //block wait
    Event wait(size_t max_wait_time = 50);
};

 template<typename IPC_TYPE>
    Poller<IPC_TYPE>::Event Poller<IPC_TYPE>::wait(size_t max_wait_time = 50)
    {
        Event e;
        return Event();
    }

Я определяю шаблон класса Poller, а также вложенный класс Event, я пишу функцию-член Poller, которая возвращает объект Event, но компилятор сообщает " Ошибка C2061 синтаксическая ошибка: идентификатор «Событие» IPC poller.cpp 8 ", как мне делать? Спасибо!

Вы пробовали Poller<IPC_TYPE>::Event?

Eljay 18.11.2018 02:37

да, тоже не удалось

Gordon 18.11.2018 02:39

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

Abhinav 18.11.2018 02:50

Как насчет typename Poller<IPC_TYPE>::Event?

Eljay 18.11.2018 02:55

Мне действительно нужно было бы увидеть отклонение события ... Он должен существовать за пределами частной области класса, или, если он существует в общедоступном пространстве класса, имя класса всегда будет частью имени типа, например Poller <IPC_TYPE> :: Event

johnathan 18.11.2018 02:57

Компилятор не может найти определение события, поэтому, пожалуйста, опубликуйте свой заголовочный файл.

johnathan 18.11.2018 02:58

Внутри структуры вашего класса это должен быть std::shared_ptr<IPC> ipc; или должен быть std::shared_ptr<IPC_TYPE> ipc;?

Francis Cugler 18.11.2018 04:26

Что такое IPC ???

curiousguy 18.11.2018 05:41
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
8
244
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Компилятор не знает, является ли Poller<IPC_TYPE>::Event переменной-членом Poller<IPC_TYPE> или вложенным типом.

Таким образом, мы должны ввести typename, чтобы устранить эту двусмысленность следующим образом:

ДЕМО уже здесь.

template<typename IPC_TYPE>
typename Poller<IPC_TYPE>::Event Poller<IPC_TYPE>::wait(size_t max_wait_time)
{
    Event e;
    return Event();
}
Ответ принят как подходящий

Глядя на ваш текущий код:

template<typename IPC_TYPE>
class Poller {    
public:
    struct Event {
        std::shared_ptr<IPC> ipc;
        enum Status
        {
            NONE = 0, POLLIN = 1, POLLHUP = 2, MessageArrival = 3
        } status;
    };

    //block wait
    Event wait(size_t max_wait_time = 50);
};

template<typename IPC_TYPE>
Poller<IPC_TYPE>::Event Poller<IPC_TYPE>::wait(size_t max_wait_time = 50) {
    Event e;
    return Event();
}

Я заметил несколько проблем:

  • 1) std::shared_ptr<IPC> ipc; Я считаю, что должен быть std::shared_ptr<IPC_TYPE> ipc;
  • 2) user:Hiroki уже ответил - typename необходимо использовать перед Poller<IPC_TYPE>::Event, чтобы объявить имя типа, чтобы компилятор знал, как распознать ваше предполагаемое использование. Обратитесь к его ответу для более подробного описания и более полного объяснения того, зачем вам нужен typename.
  • 3) Поскольку вы объявляете функцию вне тела суперкласса, MSVS 2017 CE выдает ошибку компилятора о наличии значения по умолчанию. (Увидеть ниже).
  • 4) Не уверен, что вы создаете временный ... Затем создаете и возвращаете экземпляр с помощью его конструктора, или если template argument будет каким-то functor или function pointer, который вы вызываете.
  • 5) У вас есть член std::shared_ptr<IPC_TYPE> в Event, но вы не видите динамической памяти, создаваемой для типа IPC_TYPE. Поэтому я добавил определяемый пользователем конструктор по умолчанию, который устанавливает this, чтобы видеть, как конструкторы, деструкторы, операторы, функции-члены и т. д. Объекта вызываются, создаются и уничтожаются должным образом.

(3) - Ошибка компилятора:

1>------ Build started: Project: StackQA, Configuration: Debug Win32 ------
1>main.cpp
1>c:\users\...\main.cpp(41): error C5037: 'Poller<IPC_TYPE>::wait': an out-of-line definition of a member of a class template cannot have default arguments
1>Done building project "StackQA.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Исправить указанную выше ошибку компилятора можно двумя способами:

  • A) Удаление значения по умолчанию, которое в определении находится за пределами суперкласса.
  • Б) Написание тела функции внутри внутреннего класса. Если вы решили выбрать этот метод написания тела вашей функции; он фактически устранит всю необходимость и цель вашего вопроса, в первую очередь, поскольку вы определяете его внутри внутреннего класса.

Вот рабочий пример вашего класса выше:

#include <iostream>
#include <exception>
#include <memory>

// Classes A & B are just basic classes with ctor & dtor displaying a message
class A {
public:
    A() { std::cout << "A CTOR called\n"; }
    ~A() { std::cout << "A DTOR called\n"; }
};

class B {
public:
    B() { std::cout << "B CTOR called\n"; }
    ~B() { std::cout << "B DTOR called\n"; }
};

// Classes C & D are functors where their operator invokes a message to be displayed
class C {
public:
    void operator()() { std::cout << "Functor C called\n"; }
};

class D {
public:
    void operator()() { std::cout << "Functor D called\n"; }
};

template <typename IPC_TYPE>
class Poller {
public:
    struct Event {
        std::shared_ptr<IPC_TYPE> ipc; // Made correction here from IPC to IPC_TYPE
        enum Status {
            NONE = 0,
            POLLIN = 1,
            POLLHUP = 2,
            MESSAGE_ARRIVAL = 3, // Changed to All Caps... (personal preference)
        } status;

            // Added this constructor to actually make a shared_ptr of IPC_TYPE
        Event() {
            ipc = std::make_shared<IPC_TYPE>();
        }    
    };

    // Defined the function body within the inner class which also prevents your compiler error.
    Event wait( size_t max_wait_time = 50 ) {
        // Not sure of your intentions here, but for demonstration purposes
        // I've just commented out the temporary and just returned the ctor
        // Event e;
        return Event();
    }
};

// To define it outside of class remove the body from the inner class above,
// uncomment this section, and don't forget to use `typename`.
// Also make sure that your parameter does not have a default value here.
/*template<typename IPC_TYPE>
typename Poller<IPC_TYPE>::Event Poller<IPC_TYPE>::wait( size_t wait_time ) {
    // Not sure of your intentions here, but for demonstration purposes
    // I've just commented out the temporary and just returned the ctor
    //Event e;
    return Event();
}
*/    

int main() {
    try {
        Poller<A> p1;
        p1.wait( 10 );

        Poller<B> p2;
        p2.wait( 12 );

        Poller<C> p3;       
        Poller<C>::Event e1 = p3.wait( 7 );
        e1.ipc->operator()();

        Poller<D> p4;
        Poller<D>::Event e2 = p4.wait( 9 );
        e2.ipc->operator()();

    } catch( std::runtime_error& e ) {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

-Output-

A CTOR called
A DTOR called
B CTOR called
B DTOR called
Functor C called
Functor D called

Другие вопросы по теме