I've been using a dirty trick where I use unnamed namespaces to specify different behavior for each file (it is for unit-testing). It feels like it shouldn't be well-defined, but it works on every major compiler released in the past six years.
I first forward-declare a bunch of classes in an anonymouse namespace:
namespace {
class context_check;
class context_block;
class register_test;
} // namespace
Then I declare a class and make these classes friend
s:
struct test_case
{
// ...
};
class context {
// ...
private:
// TODO: this feels like ODR-violation...
friend class context_check;
friend class context_block;
friend class register_test;
private:
void add_test(test_case&& test)
{
// ...
}
// ...
};
And in each cpp file I have following declarations (for tha sake of simplicity I copy and pasted them here, but in reality I declare the content of unnamed namespace in a header):
// A.cpp
namespace {
extern context file_context;
class register_test {
public:
register_test(const char* test_name, test_case&& test)
{
file_context.add_test(std::move(test));
}
};
} // namespace
register_test register_test_1( test_case{"test1"} );
// B.cpp
namespace {
extern context file_context;
class register_test {
public:
register_test(const char* test_name, test_case&& test)
{
file_context.add_test(std::move(test));
}
};
} // namespace
register_test register_test_2( test_case{"test2"} );
So each TU has its own definitions of register_test
, context_check
etc.
Is this well-defined? Feels like it should be an UB...