
From: Stewart, Robert
- The implementation of assignable_archetype defines private default and copy constructors, so for example assignable_archetype<copy_constructible_archetype<>> will not actually be copy constructible. The same for convertible_to_archetype and convertible_from_archetype, but additionally with copy assignment. Is this by purpose?
I should think that's by design. The archetypes are to validate a particular concept checking class, so a copyable or default constructible archetype for Assignable would be wrong.
I wouldn't say it's wrong. If you can combine several concepts, you should be able to combine the corresponding archetypes too. If your template requires more than one concept (e.g., a type that is BOTH copyable AND assignable), then without the ability of chaining you would have to write your own archetypes in all but the most trivial cases.
I would. The purpose of an Assignable archetype is to test that a type that is assignable, but possibly neither default nor copy constructible, satisfies the concept. That is, the Assignable concept checker should not impose *any* other criteria on its parameterizing type.
I guess you could've misunderstood what I ask for - it's not making the extra special functions public but rather removing them completely. This allows for composition while still it's not making the archetypes looser than required. The actual code I use is: template <typename T = int> class null_archetype { null_archetype(); null_archetype(const null_archetype &); null_archetype & operator = (const null_archetype &); ~null_archetype(); }; template < typename Base = null_archetype<> > struct copy_constructible_archetype : public Base { copy_constructible_archetype(const copy_constructible_archetype &); ~copy_constructible_archetype(); }; template < typename Base = null_archetype<> > struct assignable_archetype : public Base { assignable_archetype & operator = (const assignable_archetype &); }; How is assignable_archetype<> default or copy constructible now? It's not unless you combine it - for example only assignable_archetype<copy_constructible_archetype<>> is both assignable and copy constructible. In comparison, the current implementation of the classes is: template <class T = int> class null_archetype { private: null_archetype() { } null_archetype(const null_archetype&) { } null_archetype& operator=(const null_archetype&) { return *this; } public: null_archetype(detail::dummy_constructor) { } }; template <class Base = null_archetype<> > class copy_constructible_archetype : public Base { public: copy_constructible_archetype() : Base(static_object<detail::dummy_constructor>::get()) { } copy_constructible_archetype(const copy_constructible_archetype&) : Base(static_object<detail::dummy_constructor>::get()) { } copy_constructible_archetype(detail::dummy_constructor x) : Base(x) { } }; template <class Base = null_archetype<> > class assignable_archetype : public Base { assignable_archetype() { } assignable_archetype(const assignable_archetype&) { } public: assignable_archetype& operator=(const assignable_archetype&) { return *this; } assignable_archetype(detail::dummy_constructor x) : Base(x) { } }; Now: - assignable_archetype<copy_constructible_archetype<>> is not copy constructible, - assignable_archetype<default_constructible_archetype<>> is not default constructible, - copy_constructible_archetype<> is also default constructible, - assignable_archetype<> is also destructible (which it doesn't necessarily have to be). Either I'm overlooking something or the current implementation is simply wrong and needs to be fixed.
Even if so, not all combinations are possible.
Could you give an example of an impossible combination?
The OP's! Seriously, my point is that making a particular archetype restrict its interface might generally prevent certain combinations.
But why you'd want to prevent certain combinations at all? Is there anything wrong with combining archetypes? If not, than an archetype doesn't have to (and shouldn't) restrict its interface (by "restricting" I don't mean "not providing", but "prevent from providing by combined archetypes"). Assuming you use null_archetype as the root base class, you don't need to restrict anything because it is sufficient not to declare functions that are not needed. They will not be provided unless you chain the archetype with another archetype that provides them. OTOH, restricting them will practically break chaining (as it does now).
In order to make the Assignable archetype neither default nor copy constructible, to ensure that the concept checker doesn't require those capabilities, it cannot be combined with CopyConstructible's or DefaultConstructible's archetypes, at least not as the derivate.
Sorry, but could you give a code example? I still don't see your point. assignable_archetype<> defined as above is not copy nor default constructible. assignable_archetype<default_constructible_archetype<copy_constructible_arch etype<>>> is. Do you mean that chaining archetypes like this should be forbidden? If so, why? After all, if you can combine concepts, you must be able to combine archetypes as well or otherwise you're not able to test the concepts at all. For example, if you have a function template: template<typename T> void f(const T &) { BOOST_CONCEPT_ASSERT((Assignable<T>)); BOOST_CONCEPT_ASSERT((CopyConstructible<T>)); ... } Then how do you test this function without chaining? You have to write your own simple archetype that combines assignable_archetype<> and copy_constructible_archetype<>. I don't see any point in doing this repetitive and error-prone work when you could simply use assignable_archetype<copy_constructible_archetype<>>. Best regards, Robert