Click here to Skip to main content
15,669,524 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
[EDIT] the solution via workaround is to define a local variable w/ the stored optional value and cast it i.e. to wit as below
auto _const_ptr_ = *optional_const_ptr;
auto _ptr_ = const_cast<add_pointer_t<remove_const_t<remove_pointer_t<decltype(_const_ptr_)>>>>(_const_ptr_);
Greetings Kind Regards i am attempting to cast away const of a pointer target type so that the pointer no longer points to a const type via
it works as shown in first section of code below however in the 2nd section it fails to compile w/ the error message as shown if the pointer being converted is enclosed in an optional<> . i do not understand where the 2nd * in cfoo** is coming from in '_Ty' to 'const cfoo **' in error message . please advise Thank You Kindly
// error C2440: 'const_cast': cannot convert from '_Ty' to 'const cfoo **'
// with
// [
// _Ty=const cfoo *
// ]
// message : Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or parenthesized function-style cast

#include <optional>
#include <iostream>
#include <cstddef>
#include <type_traits>

using namespace std;

struct cfoo {};

int main()
	const cfoo _cfoo;
		const cfoo* const_cfoo_ptr = &_cfoo;
		cout << typeid(decltype(const_cfoo_ptr)).name() << endl;
		auto cfoo_ptr = const_cast<add_pointer_t<remove_const_t<remove_pointer_t<decltype(const_cfoo_ptr)>>>>(const_cfoo_ptr);
		cout << typeid(decltype(cfoo_ptr)).name() << endl;
		optional<const cfoo*>  optional_const_cfoo_ptr = &_cfoo;
		cout << typeid(decltype(*optional_const_cfoo_ptr)).name() << endl;
		// line below fails to compile w/ error message shown
		auto cfoo_ptr = const_cast<add_pointer_t<remove_const_t<remove_pointer_t<decltype(*optional_const_cfoo_ptr)>>>>(*optional_const_cfoo_ptr);
		cout << typeid(decltype(cfoo_ptr)).name() << endl;

What I have tried:

not too much . other than demonstrating cast works if on type not contained in optional<>
Updated 21-Feb-23 7:03am

1 solution

I'm not sure where you're going wrong there. But that seems entirely too complicated. Surely, all you need to do is use const_cast<> without all of the intermediate steps using add/remove_pointer_t?
const cfoo _cfoo;
const cfoo const_cfoo_ptr = &_cfoo;   // has type (const cfoo*)
auto cfoo_ptr = const_cast<add_pointer_t<remove_const_t<remove_pointer_t<decltype(const_cfoo_ptr)>>>>(const_cfoo_ptr);  // has type (cfoo*)
auto cfoo2_ptr = const_cast<cfoo*>(const_foo_ptr); // has type (cfoo*)

// likewise
optional<const cfoo*> optional_const_cfoo_ptr = &_cfoo;  // has type (std::optional<cfoo const*>)
auto const_cfoo_ptr_from_optional = *optional_const_cfoo_ptr; // has type (cfoo const*)
auto cfoo_ptr_from const_optional = const_cast<cfoo *>(*optional_const_cfoo_ptr); // has type (cfoo *)

Which gets you to a pointer to a cfoo, which is what I think you're trying to achieve.
Share this answer
BernardIE5317 21-Feb-23 12:55pm    
thank you for your kind assistance . the full problem is somewhat more than presented . in actuality the complicated cast is a macro so it needs to determine the pointer target type . for some reason it did not work for a pointer stored in an optional . hence my post . i found a work around i.e. to first declare a local variable w/ the stored value then cast it via the macro -Best

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900