2013-06-09 1 views
1

У меня есть проблема с компиляцией этот код g++ -std=c++11 аргумент:Еще один абстрактный вопрос класса в C++ с затворами

#include <iostream> 
#include <unordered_map> 
#include <functional> 
#include <iostream> 
using namespace std;; 

template <typename T> class opt { 
    public: 
     opt() {}; 
     ~opt() {}; 
     virtual int isEmpty() = 0; 
     virtual T getObject() = 0; 
}; 

template <typename T> class oopt : public opt<T> { 
    private: 
     T ret; 
    public: 
     oopt(T obj) { ret = obj; }; 
     ~oopt() override; 
     int isEmpty() { return 0; }; 
     T getObject() { return ret; }; 
}; 
int main(void) { 

    function<opt<int>(int)> fu = [](int j) { return (oopt<int>(10)); }; 

    return 1; 
} 

Этот код возвращает следующую ошибку:

assoc_array.cc: In instantiation of ‘class oopt<int>’: 
assoc_array.cc:68:63: required from here 
assoc_array.cc:29:3: error: ‘oopt<T>::~oopt() [with T = int]’ marked override, but does not override 
In file included from assoc_array.cc:3:0: 
/usr/include/c++/4.7/functional: In instantiation of ‘static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Res = opt<int>; _Functor = main()::<lambda(int)>; _ArgTypes = {int}]’: 
/usr/include/c++/4.7/functional:2298:6: required from ‘std::function<_Res(_ArgTypes ...)>::function(_Functor, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type) [with _Functor = main()::<lambda(int)>; _Res = opt<int>; _ArgTypes = {int}; typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type = std::function<opt<int>(int)>::_Useless]’ 
assoc_array.cc:68:67: required from here 
/usr/include/c++/4.7/functional:1909:7: error: invalid abstract return type for function ‘static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Res = opt<int>; _Functor = main()::<lambda(int)>; _ArgTypes = {int}]’ 
assoc_array.cc:7:29: note: because the following virtual functions are pure within ‘opt<int>’: 
assoc_array.cc:11:15: note:  int opt<T>::isEmpty() [with T = int] 
assoc_array.cc:12:13: note:  T opt<T>::getObject() [with T = int] 
In file included from assoc_array.cc:3:0: 
/usr/include/c++/4.7/functional:1912:40: error: cannot allocate an object of abstract type ‘opt<int>’ 
assoc_array.cc:7:29: note: since type ‘opt<int>’ has pure virtual functions 
In file included from assoc_array.cc:3:0: 
/usr/include/c++/4.7/functional:1743:2: error: ‘static _Functor* std::_Function_base::_Base_manager<_Functor>::_M_get_pointer(const std::_Any_data&) [with _Functor = main()::<lambda(int)>]’, declared using local type ‘main()::<lambda(int)>’, is used but never defined [-fpermissive] 

Где моя ошибка, используя замыкания со статическим литьем на интерфейс? Я уже читал подобные ответы (C++ and inheritance in abstract classes, C++ - "Member function not declared" in derived class), но кажется, что во время компиляции ошибка не возникает, если я удалю определение закрытия. Заранее спасибо.

EDIT

Даже со следующим кодом:

#include <iostream> 
#include <unordered_map> 
#include <functional> 
#include <iostream> 
using namespace std;; 

template <typename T> class opt { 
    public: 
     opt<T>(T) {}; 
     ~opt<T>() {}; 
     virtual int isEmpty() = 0; 
     virtual T getObject() = 0; 
}; 

template <typename T> class oopt : public opt<T> { 
    private: 
     T ret; 
    public: 
     oopt<T>(T obj) { ret = obj; }; 
     ~oopt<T>() override; 
     int isEmpty() { return 0; }; 
     T getObject() { return ret; }; 
}; 
int main(void) { 

    function<opt<int>(int)> fu = [](int j) { return (oopt<int>(10)); }; 

    return 1; 
} 

Я до сих пор имеют следующую компиляцию вопросы:

assoc_array.cc: In instantiation of ‘class oopt<int>’: 
assoc_array.cc:26:64: required from here 
assoc_array.cc:20:4: error: ‘oopt<T>::~oopt() [with T = int]’ marked override, but does not override 
assoc_array.cc: In instantiation of ‘oopt<T>::oopt(T) [with T = int]’: 
assoc_array.cc:26:64: required from here 
assoc_array.cc:19:19: error: no matching function for call to ‘opt<int>::opt()’ 
assoc_array.cc:19:19: note: candidates are: 
assoc_array.cc:9:4: note: opt<T>::opt(T) [with T = int] 
assoc_array.cc:9:4: note: candidate expects 1 argument, 0 provided 
assoc_array.cc:7:30: note: constexpr opt<int>::opt(const opt<int>&) 
assoc_array.cc:7:30: note: candidate expects 1 argument, 0 provided 
In file included from assoc_array.cc:3:0: 
/usr/include/c++/4.7/functional: In instantiation of ‘static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Res = opt<int>; _Functor = main()::<lambda(int)>; _ArgTypes = {int}]’: 
/usr/include/c++/4.7/functional:2298:6: required from ‘std::function<_Res(_ArgTypes ...)>::function(_Functor, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type) [with _Functor = main()::<lambda(int)>; _Res = opt<int>; _ArgTypes = {int}; typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type = std::function<opt<int>(int)>::_Useless]’ 
assoc_array.cc:26:68: required from here 
/usr/include/c++/4.7/functional:1909:7: error: invalid abstract return type for function ‘static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Res = opt<int>; _Functor = main()::<lambda(int)>; _ArgTypes = {int}]’ 
assoc_array.cc:7:30: note: because the following virtual functions are pure within ‘opt<int>’: 
assoc_array.cc:11:16: note:  int opt<T>::isEmpty() [with T = int] 
assoc_array.cc:12:14: note:  T opt<T>::getObject() [with T = int] 
In file included from assoc_array.cc:3:0: 
/usr/include/c++/4.7/functional:1912:40: error: cannot allocate an object of abstract type ‘opt<int>’ 
assoc_array.cc:7:30: note: since type ‘opt<int>’ has pure virtual functions 
In file included from assoc_array.cc:3:0: 
/usr/include/c++/4.7/functional:1743:2: error: ‘static _Functor* std::_Function_base::_Base_manager<_Functor>::_M_get_pointer(const std::_Any_data&) [with _Functor = main()::<lambda(int)>]’, declared using local type ‘main()::<lambda(int)>’, is used but never defined [-fpermissive] 
+0

Непохоже, вы даже можете использовать eopt в основном, просто избавиться от него для нашего ради – aaronman

+0

eopt используется в некоторой части кода, который не заинтересован в descripted ошибки. – jackb

+0

Точно, когда вы публикуете на SO, то в любом случае самое интересное сделать код максимально простым. – aaronman

ответ

0

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

#include <iostream> 
#include <unordered_map> 
#include <functional> 
#include <iostream> 
#include <memory> 

using namespace std; 

//I need shared_pointers in order to gain the C++ dynamic casting 
template <typename T> class Ptr { 
    shared_ptr<T> ptr; 

    public: 
     Ptr(T* obj) : ptr{obj} {}; 
     Ptr(shared_ptr<T> obj) : ptr{obj} {}; 

     ~Ptr() { }; 

     template <typename U> Ptr<U> Cast(); 

     T* operator->() const {return &(*this->ptr);} 
     operator T() const { return (*this->ptr); }; 

}; 

template <typename T> template <typename U> Ptr<U> Ptr<T>::Cast(){ 
    return Ptr<U>{dynamic_pointer_cast<U>(ptr)}; 
}; 


template <typename T> class opt { 
    protected: 
     T ret;     
    public: 
     ~opt() {}; 
     virtual int isEmpty() = 0; 
     virtual T* getObject() = 0; 
     operator T() const { return ret; }; 
}; 

template <typename T> class oopt : public opt<T> { 
    public: 
    oopt(T obj) { 
     this->ret = obj; 
    }; 
    int isEmpty() { return 1; }; 
    T* getObject() { return &this->ret; } 
}; 

template <typename T> class eopt : public opt<T> { 
    public: 
    eopt() { }; //for downcasting matters 
    T* getObject() { return nullptr; } // 
    int isEmpty() { return 1; }; 
}; 

int main(void) { 

    Ptr<oopt<int>> u(new oopt<int>(500)); 
    Ptr<opt<int>> w = u.Cast<opt<int>>(); 
    cout << (*(w->getObject())) << "\n" ; 

    Ptr<opt<int>> none(new eopt<int>()); 
    w = none.Cast<opt<int>>(); 
    if ((w->getObject()) == nullptr) { 
     cout << "null" << "\n"; 
    } 

    return 1; 

} 
0

Ok сначала избавиться от переопределения и сделать деструктор virtual (они всегда должны быть унаследованы). Также деструктор не реализован в базовом классе

#include <iostream> 
#include <unordered_map> 
#include <functional> 
#include <iostream> 
using namespace std;; 

template <typename T> class opt { 
    public: 
     opt() {}; 
     virtual ~opt() {}; 
     virtual int isEmpty() = 0; 
     virtual T getObject() = 0; 
}; 

template <typename T> class oopt : public opt<T> { 
    private: 
     T ret; 
    public: 
     oopt(T obj) { ret = obj; }; 
     ~oopt(){}; 
     int isEmpty() { return 0; }; 
     T getObject() { return ret; }; 
}; 
int main(void) { 

    function<opt<int>(int)> fu = [](int j) { return (oopt<int>(10)); }; 

    return 1; 
} 

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

+0

ну, в определении oopt Я утверждаю, что: 'oopt (T obj) {ret = obj; }; ' поэтому, с' T = int', у меня есть конструктор int, поэтому я должен реализовать его так же, как и для суперкласса? – jackb

+0

Это 'oopt' не' opt', честно это трудно прочитать, рассматривая возможность дать вашим классам более описательные имена или сократить код, чтобы положить его на SO – aaronman

+0

Ну, учитывая ваш код, у меня все еще есть следующая ошибка: http://pastebin.com/BphD63pu – jackb

1

Как gcc является стандартным компилятором, его ошибки не самые чистые, даже больше с C++, чем C, поэтому я обычно компилирую все как с clang, так и с gcc, чтобы быть уверенным. скомпилирован с лязгом: я получил это с aaronman кодом, т

clang++ -std=c++11 test.cc                                            ~ 
test.cc:20:20: error: only virtual member functions can be marked 'override' 
     ~oopt<T>() override; 
        ^~~~~~~~ 
test.cc:26:54: note: in instantiation of template class 'oopt<int>' requested here 
    function<opt<int>(int)> fu = [](int j) { return (oopt<int>(10)); }; 
                ^
test.cc:19:9: error: constructor for 'oopt<int>' must explicitly initialize the base class 'opt<int>' which does not have a default constructor 
     oopt<T>(T obj) { ret = obj; }; 
     ^
test.cc:26:54: note: in instantiation of member function 'oopt<int>::oopt' requested here 
    function<opt<int>(int)> fu = [](int j) { return (oopt<int>(10)); }; 
                ^
test.cc:7:29: note: 'opt<int>' declared here 
template <typename T> class opt { 
          ^
2 errors generated. 

и это для вашей первой:

clang++ -std=c++11 test2.cc                                            ~ 
test2.cc:20:17: error: only virtual member functions can be marked 'override' 
     ~oopt() override; 
       ^~~~~~~~ 
test2.cc:26:54: note: in instantiation of template class 'oopt<int>' requested here 
    function<opt<int>(int)> fu = [](int j) { return (oopt<int>(10)); }; 
                ^
1 error generated. 

после исправления этих ошибок лязг дал мне это во время связывания:

clang++ -o -std=c++11 test2.o -Wall -Werror                                        ~ 
test2.o: In function `std::_Function_handler<opt<int> (int), main::$_0>::_M_invoke(std::_Any_data const&, int)': 
test2.cc:(.text+0x1a7): undefined reference to `oopt<int>::~oopt()' 
test2.o:(.rodata._ZTV4ooptIiE[_ZTV4ooptIiE]+0x10): undefined reference to `oopt<int>::~oopt()' 
test2.o:(.rodata._ZTV4ooptIiE[_ZTV4ooptIiE]+0x18): undefined reference to `oopt<int>::~oopt()' 
clang: error: linker command failed with exit code 1 (use -v to see invocati 

)

это неточно a nswer, но это могло бы помочь много

+0

Спасибо: основная проблема в том, что некоторые вещи скомпилированы g ++, но не clang ++. Кстати, я на самом деле работаю над решением ... – jackb

+0

Да, это не мой код для компиляции – aaronman

Смежные вопросы