compile error "any.h"

Hi,
There's a topic on codeproject that talks about implementing a high performance 'boost any'
http://www.codeproject.com/Articles/11250/High-Performance-Dynamic-Typing-in-C-using-a-Repla

The follow code compiles on vs2012, but not on MinGW 4.8.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
 
#pragma once
 
#include <stdexcept>

namespace anyimpl 
{
	struct bad_any_cast 
	{
	};

	struct empty_any 
	{
	};

	struct base_any_policy
	{

		virtual void static_delete( void** x) = 0;

		virtual void copy_from_value(void const* src, void** dest) = 0;

		virtual void clone(void* const* src, void** dest) = 0;

		virtual void move(void* const* src, void** dest) = 0;

		virtual void* get_value(void** src) = 0;

		virtual size_t get_size() = 0;

	};

	template<typename T>
	struct typed_base_any_policy : base_any_policy 
	{
		virtual size_t get_size() { return sizeof(T); } 
	};

	template<typename T>
	struct small_any_policy : typed_base_any_policy<T> 
	{

		virtual void static_delete(void** x) { }

		virtual void copy_from_value(void const* src, void** dest) 
		{
			//This used to be:
			//new(dest) T(*reinterpret_cast<T const*>(src)); 
			//But this is the small_any_policy, and ints and other small objects
			//shouldn't need to be pointed to by an object.
			//In this case, we are really receiving the address of the the 'object' variable
			*dest = *(reinterpret_cast<void**>((const_cast<void*>(src))));
		}

		virtual void clone(void* const* src, void** dest) { *dest = *src; }

		virtual void move(void* const* src, void** dest) { *dest = *src; }

		virtual void* get_value(void** src) { return reinterpret_cast<void*>(src); }

	};

	template<typename T>
	struct remove_const 
	{
		typedef T type;
	};

	template<typename T> 
	struct remove_const<const T>
	{ 
		typedef T type; 
	};

	template<typename T>
	struct big_any_policy : typed_base_any_policy<T> 
	{
		virtual void static_delete( void** x) 
		{
			if (*x) 
			{
				delete (*reinterpret_cast< (remove_const<T>::type**) >(x));
			}
			*x = NULL;
		}

		virtual void copy_from_value(void const* src, void** dest) 
		{ 
			*dest = new remove_const<T>::type(*reinterpret_cast<T const*>(src));
		}

		virtual void clone(void* const* src, void** dest)
		{ 
			*dest = new remove_const<T>::type(**reinterpret_cast<T* const*>(src));
		}

		virtual void move(void* const* src, void** dest) 
		{ 
			(*reinterpret_cast<remove_const<T>::type**>(dest))->~T(); 
			**reinterpret_cast<remove_const<T>::type**>(dest) = **reinterpret_cast<T* const*>(src);
		}

		virtual void* get_value(void** src) { return *src; }
	};

	template<typename T>
	struct choose_policy 
	{
		typedef big_any_policy<T> type;
	};

	template<typename T> 
	struct choose_policy<T*>
	{ 
		typedef small_any_policy<T*> type; 
	};

	struct any; //Forward declaration

	/// Choosing the policy for an any type is illegal, but should never happen.
	/// This is designed to throw a compiler error.
	template<>
	struct choose_policy<any> 
	{
		typedef void type;
	};

	/// Specializations for small types.
#define SMALL_POLICY(TYPE) template<> struct choose_policy<TYPE> { typedef small_any_policy<TYPE> type; };
	SMALL_POLICY(signed char);
	SMALL_POLICY(unsigned char);
	SMALL_POLICY(signed short);
	SMALL_POLICY(unsigned short);
	SMALL_POLICY(signed int);
	SMALL_POLICY(unsigned int);
	SMALL_POLICY(signed long);
	SMALL_POLICY(unsigned long);
	SMALL_POLICY(float);
	SMALL_POLICY(bool);
	SMALL_POLICY(const signed char);
	SMALL_POLICY(const unsigned char);
	SMALL_POLICY(const signed short);
	SMALL_POLICY(const unsigned short);
	SMALL_POLICY(const signed int);
	SMALL_POLICY(const unsigned int);
	SMALL_POLICY(const signed long);
	SMALL_POLICY(const unsigned long);
	SMALL_POLICY(const float);
	SMALL_POLICY(const bool);
#undef SMALL_POLICY

	/// This function will return a different policy for each type. 
	template<typename T>
	base_any_policy* get_policy() 
	{
		static typename choose_policy<T>::type policy;
		return &policy;
	};

}  //End of anyimpl namespace

struct any 
{
private:
	// fields
	anyimpl::base_any_policy* policy;
	void* object;

public:
	/// Initializing constructor.
	template <typename T>
	//This used to be:
	//any(const T& x) : policy(anyimpl::get_policy<anyimpl::empty_any>()), object(NULL) {
	//I am changing it to force the initial construction to use the small_policy:
	any(const T& x) : policy(anyimpl::get_policy<unsigned int>()), object(NULL) 
	{
		assign(x);
	}      

	/// Empty constructor. 
	//This used to be:
	//any() : policy(anyimpl::get_policy<anyimpl::empty_any>()), object(NULL) {
	//But why should an empty 'any' receive a default 'big_any_policy'???
	//This starts calling 'new' and 'delete' under the hood.
	//So let's try the following to force a small_policy:
	any() : policy(anyimpl::get_policy<unsigned int>()), object(NULL) 
	{
	}

	/// Special initializing constructor for string literals. 
	any(const char* x) : policy(anyimpl::get_policy<anyimpl::empty_any>()), 
		object(NULL) 
	{
			assign(x);
	}

	/// Copy constructor. 
	any(const any& x) : policy(anyimpl::get_policy<anyimpl::empty_any>()), object(NULL) 
	{
		assign(x);
	}

	/// Destructor. 
	~any() 
	{
		policy->static_delete(&object);
	}

	/// Assignment function from another any. 
	any& assign(const any& x) 
	{
		reset();
		policy = x.policy;
		policy->clone(&x.object, &object);
		return *this;
	}

	/// Assignment function. 
	template <typename T>
	any& assign(const T& x)
	{
		reset();
		policy = anyimpl::get_policy<T>();
		policy->copy_from_value(&x, &object);
		return *this;
	}

	/// Assignment operator.
	template<typename T>
	any& operator=(const T& x) 
	{
		return assign(x);
	}

	any& operator=(const any & x)
	{
		/*policy = x.policy;
		policy->copy_from_value(&x.object, &object);
		return *this;*/
		reset();
		return assign(x);
	}

	any& operator()(const any & x) 
	{
		policy = x.policy;
		policy->copy_from_value(&x.object, &object);
		return *this;
	}

	/// Assignment operator, specialed for literal strings. 
	/// They have types like const char [6] which don't work as expected. 
	any& operator=(const char* x) 
	{
		return assign(x);
	}

	/// Utility functions
	any& swap(any& x) 
	{
		std::swap(policy, x.policy);
		std::swap(object, x.object);
		return *this;
	}

	/// Cast operator. You can only cast to the original type.
	template<typename T>
	T& cast() 
	{
		if (policy != anyimpl::get_policy<T>()) 
		{
			throw anyimpl::bad_any_cast();
		}
		T* r = reinterpret_cast<T*>(policy->get_value(&object)); 
		return *r;
	}

	/// Returns true if the any contains no value. 
	bool empty() const 
	{
		return policy == anyimpl::get_policy<anyimpl::empty_any>();
	}

	/// Frees any allocated memory, and sets the value to NULL.
	void reset() 
	{
		policy->static_delete(&object);
		//The following used to be:
		//policy = anyimpl::get_policy<anyimpl::empty_any>();
		//But why should the policy default to the big_any_policy?  Therefore,:
		policy = anyimpl::get_policy<unsigned int>();
	}

	/// Returns true if the two types are the same. 
	bool isA(const any& x) const 
	{
		return policy == x.policy;
	}

	template<typename T>
	bool isA() 
	{
		return policy == anyimpl::get_policy<T>();
	}

	template <typename T>
	operator T() {
		return cast<T>();
	}

}; //End of 'any' struct definition
 

int main() {}


the compile error:
G:\test.cpp:82:32: error: expected type-specifier before '(' token
     delete (*reinterpret_cast< (remove_const<T>::type**) >(x));
                                ^
G:\\test.cpp:82:32: error: expected '>' before '(' token


How to solve this error?

Thanks.
Last edited on
The name of a type is not an expression; you can't just keep putting redundant parenthesis around things that are not expressions.

1
2
3
4
5
6
7
8
int i = 100 ;
double d ;

// d = static_cast< (double) >(i) ; // *** error: expected type-specifier before '(' token
d = static_cast<double>(i) ; // fine

// d = ((double)) i ; // *** error
d = (double)(i) ; // fine 


#include <type_traits> and then:

1
2
// delete (*reinterpret_cast< (remove_const<T>::type**) >(x));
delete *reinterpret_cast< typename std::remove_const<T>::type** >(x) ;

etc.

Use boost::any; don't trust people who write foul stuff of this kind.
It works, thank you JLBorges.
Topic archived. No new replies allowed.