Since you have clarified your question a lot, my first answer does not apply any more and I'll remove-edit it to give you something that might fit better:
Updated answer:
You want to constrain the template to accept only types that are typedeffed inside your MyClass template. Such constraints are usually achieved by application of SFINAE, especially by std::enable_if
(or boost::enable_if
, if your library lacks that part of C++11 support). Sadly, there is no traits like a is_typedeffed_inside
that could be used for your case. It's even worse: there is no way to write such a trait just using the plain typedefs, since there is nothing special about being typedeffed inside a given class - the compiler has no way to determine (and is not interested in) if a given known type has some alias name for it somewhere.
But if your typedefs are just the ones you show in your question, I have good news for you: you need exactly two operator<<
for that:
- One for
boost::dynamic_bitset<>
, since that is the BoolTable for any MyClass instantiation. - Another one, templated, for
std::vector<T>
, since that is the MsgTable for each correspondingMyClass<T>
.
The downside is, that with this templated operator<<
, you'd be able to output any std::vector<FooBar>
, even if FooBar
is completely unrelated to any use of MyClass. But that holds for any other possible implementation of the proper operator<<
's - if there's no explicit restriction on the MSG parameter, there's no restriction on a FooBar making a std::vector<FooBar>
a viable MyClass<MSG>::MsgTable
.
My conclusion for your question: you wanted to have the operator<<
for its convenient looks, since it is normally used for thet purpose. In your case, you can provide it for MyClass<MSG>
objects, but there is no way to do so for the inner typedefs alone.
I'd implement it that way:
template <class MSG>
class MyClass {
/* ... */
public:
// instead of declaring op<< a friend, redirect to a method that has
// natural access to private members
std::ostream& printToStream(std::ostream& os) const
{
os << "Bool: ";
tableToStream (getB(), os);
os <<"\nMsg:";
tableToStream (getM(), os);
return os <<'\n';
}
private:
// make this one private so nobody can misuse it to print unrelated stuff
template <class Table>
static void tableToStream(Table const& table, std::ostream& os)
{
std::copy(begin(table), end(table), ostream_iterator(os, ", "));
}
};
template <typename MSG>
std::ostream& operator << (std::ostream& os, const MyClass<MSG>& mc)
{
return mc.printToStream(os);
}