4

In C++, I am trying to implement my own any class using C++. However, before I was able to test it (so if my implementation is bad, feel free to correct me), I got the error: error C2228: left of '.val' must have class/struct/union twice from using the value() function twice, which seems weird when it works everywhere else. The only thing I could think of would be that decltype infront of a function is causing an error, but it shouldn't:

Edit: I have updated the way of changing the variable for the template<class T> any(T V){...} constructor

class any{
protected:
    template<class T> struct variable{
    public:
        T val;
        variable(){}
        variable(T t) : val(t){}
    };
    variable<int> v;
public:
    any(){
        v.val = 0;
    }
    template<class T> any(T V){
        variable<T> nV(V);
        v = nV;
    }
    ~any(){
        delete &v;
    }
    decltype(v.val) value(){ // Error still here
        return v.val;
    }
    template<class T> static any create(T V){
        return any(V);
    }
};
Joe
  • 1,059
  • 2
  • 11
  • 21
  • 2
    `T = NewT;` is not valid syntax. Neither is `T != decltype(v.val)`. Replace the second one with `std::is_same::value`. –  Jan 06 '14 at 19:01
  • You can't change the type of a template like that, the types are hard-coded. – dutt Jan 06 '14 at 19:24
  • `~any(){ delete &v; }` does not do what you seem to think it does. That will try to deallocate memory via global operator delete, which will (most likely) crash at runtime since `v` is not allocated with global allocator new. You probably wanted something like `v.~variable()`, though that's already done in this case since `v` is a member variable of `any` (and invoking the destructor twice could cause other runtime crashes, though not likely in this example). – Sean Middleditch Jan 07 '14 at 02:12

1 Answers1

5

You seem to have a big misunderstanding about this line:

T = NewT;

In C++, the T is a template parameter and therefore it is static during compilation. You can not "set" it as it is not a variable. Unlike some dynamic languages (Python, ...) in C++ types are not objects and can not be modified during runtime. You can instantiate the template with different types (different Ts), but each is like a separate class (called a template class instantiation or class template instantiation, both are equivalent) and it is independent of the other instances.

Since the rest of your design is based on the above false assumption, you run into a lot of problems. The reason that the above line is not showing up as the first error is that it is not even instantiated before other part of the code are compiled (technically: different stages of compilation). That said, you need to understand why the above is impossible in C++ and the rest will follow. You may want to look into other implementations like Boost.Any to get some ideas on how it could be done. (Warning: It's more complicated than your approach)

Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
  • I have updated my answer to get rid of the template error, but still get the c2228 error. Would you be able to tell me what the problem is? – Joe Jan 06 '14 at 20:32
  • @Joe Probably visual studio. It compiles fine in gcc. –  Jan 06 '14 at 20:33
  • @remyabel - What do you suggest that I do then? Use GCC? – Joe Jan 06 '14 at 20:34
  • @Joe Your compiler. GCC and Clang are happy with the code now, although it is now anything but an "any" class :) – Daniel Frey Jan 06 '14 at 20:34
  • @Joe Update Visual Studio (check their blog to see C++11 updates) or change your compiler. –  Jan 06 '14 at 20:35
  • @remyabel - I downloaded VS2013 yesterday: do you think I should change my compiler then? – Joe Jan 06 '14 at 20:38