Yes. But with proper prefixes it's quite clean. Unfortunately the
standard language doesn't yet support pushing/popping macro definitions,
though individual implementations do as language extensions.
If you really want to avoid macros, /and/ want that compile time
concatenation really bad, consider something like
---
namespace my {
template< class Type > using in_ = const Type&;
template< class Type > using ref_ = Type&;
template< int n, class Item >
struct Wrapped_array_
{
using Raw = Item[n];
Raw items;
constexpr auto raw() const -> ref_<const Raw> { return items; }
};
template< int size_a, int size_b >
constexpr auto adjoined( in_<const char[size_a]> a, in_<const
char[size_b]> b )
-> Wrapped_array_<size_a + size_b - 1, char>
{
const int len_a = size_a - 1;
const int len_b = size_b - 1;
const int n = len_a + len_b + 1;
Wrapped_array_<n, char> result{};
for( int i = 0; i < len_a; ++i ) {
result.items[i] = a[i];
}
for( int i = 0; i < len_b; ++i ) {
result.items[i + len_a] = b[i];
}
result.items[n - 1] = '\0';
return result;
}
} // namespace my
#include <stdio.h>
auto main() -> int
{
constexpr auto& a = "abc";
constexpr auto& b = "def";
static constexpr auto c_wrapped = my::adjoined( a, b );
constexpr auto& c = c_wrapped.raw();
puts( c );
}
---
- Alf