>
>These two cases are indistinguishable.
Are they? While we seem to have wandered off the Boost territories, consider this: If B (== typeof(propB)) were defined effectively as
class B {
public: void get(...);
private: void set(...);
friend class A;
};
would that not have the effect desired? Conceptually you could use the CRTP pattern to mix A in to the instantiation of propB so that only A was a friend.
I don't think you can do this in real life with templates because gcc does not allow declaring template parameters as friends
(e.g., this does not compile)
template < typename T > class X { friend T; };
I would suggest using something similar as a "password type". Tested with MSVC 9
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>
#include <iostream>
template<class Type, class PasswordT=void>
class Property
{
public:
Type const& get()const
{
return value_;
}
template<class PwdT>
void set( Type const& value)
{
set_impl<PwdT, PasswordT>(value);
}
void set(Type const& value)
{
set_impl<void, PasswordT>(value);
}
private:
template<class Pwd, class ExpectedPwd>
void set_impl( Type const& value
, typename boost::enable_if<boost::is_same<Pwd, ExpectedPwd> >::type* enable =0
)
{
value_ = value;
}
private:
Type value_;
};
class A
{
private:
struct secret {};
public:
Property<int> test1;
Property<long, secret> test2;
void set_via_a(long l)
{
test2.set<secret>(l);
}
};
int main()
{
A a;
a.test1.set(10);
//a.test2.set(20); //ERROR
a.set_via_a(20);
using namespace std;
cout << "test1: " << a.test1.get()
<< "\ntest2: " << a.test2.get();
return 0;
}
Hope that helps,
Ovanes