
Hi, can anyone explain why an any_cast that adds a low-level const throws?? Example: char str[] = "a2"; boost::any ay(str); boost::any_cast<const char*>(ay); // throws, since a const is added!!! The only way to do this (without throwing), seems to be: boost::any_cast<char*>(ay); But why this mild "design deficiency"?? I call it "design deficiency", since the following is legal and works: char str2[] = "str2"; static_cast<const char *>(str2); So we should be able to add a low-level const, to make something read-only, right. Thanks for comments and explanations. n. Here's some test-code: /////// #include <iostream> #include <algorithm> #include <boost/any.hpp> int main() { char str[] = "a1"; boost::any ay(str); std::cout << "1 -- " << boost::any_cast<char *>(ay) << std::endl; strcpy(str, "a2"); /* throws!! */ //std::cout << "2 -- " << boost::any_cast<const char*>(ay) << std::endl; strcpy(str, "a3"); std::cout << "3 -- " << *boost::any_cast<char *>(&ay) << std::endl; strcpy(str, "a4"); /* segfault!! */ //std::cout << "4 -- " << *boost::any_cast<const char *>(&ay) << std::endl; char str2[] = "str2"; std::cout << "str2 -- " << static_cast<const char *>(str2) << std::endl; return 0; } ///////

On Wed, Sep 23, 2015 at 9:55 PM, nice sw123 wrote:
Hi,
can anyone explain why an any_cast that adds a low-level const throws??
Example: char str[] = "a2"; boost::any ay(str); boost::any_cast<const char*>(ay); // throws, since a const is added!!!
The only way to do this (without throwing), seems to be: boost::any_cast<char*>(ay);
But why this mild "design deficiency"??
If I change this code https://github.com/boostorg/any/blob/ed7cac4ee207b125aa25144f2674f9550def223... to template<typename ValueType> ValueType * any_cast(any * operand) BOOST_NOEXCEPT { return &static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held; /* return operand && operand->type() == boost::typeindex::type_id<ValueType>() ? &static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held : 0; */ } then I can do what I want!! Then adding low-level const is fine!!! (Probably I remove some safety, for truely illegal casts; but at least I have proof that it would be possible to add low-level const! Does any C++ guru have suggestions on integrating typesafety, but still allowing low-level const to be added? Thanks ) With the above changes, the following now actually works: same code as in first post /////// #include <iostream> #include <algorithm> #include <boost/any.hpp> int main() { char str[] = "a1"; boost::any ay(str); std::cout << "1 -- " << boost::any_cast<char *>(ay) << std::endl; strcpy(str, "a2"); std::cout << "2 -- " << boost::any_cast<const char*>(ay) << std::endl; // -> no throws !!! strcpy(str, "a3"); std::cout << "3 -- " << *boost::any_cast<char *>(&ay) << std::endl; strcpy(str, "a4"); std::cout << "4 -- " << *boost::any_cast<const char *>(&ay) << std::endl; // -> no segault !!! char str2[] = "str2"; std::cout << "str2 -- " << static_cast<const char *>(str2) << std::endl; return 0; } ///////

I was just trying some stuff here.. #include <typeinfo> #include <cassert> using T1 = const char *; using T2 = char *; assert(typeid(T1) != typeid(T2)); // assert(typeid(const T1) == typeid(const T2)); // -> damn!! seems: cannot add low-level const here But look at this: ===== template <typename T> void func(T t) { std::cout << "nonpointer" << std::endl; } template <typename T> void func(T *t) { std::cout << "pointer" << std::endl; } template <typename T> void func(const T *t) { std::cout << "pointer to const" << std::endl; } char str[] = "a1"; func("asdf"); //pointer to const func(str); // pointer func(1); // nonpointer What this tells me is: if it's not possible to add a low-level const to a typeinfo or typeindex, then we could still change the constructor of boost::any, to differentiate between types. Any comments, hints or pointers welcome. (You may have noticed... template and meta is not my strength yet... but I hope to learn)
participants (1)
-
nice sw123