Для C ++ 14 и выше, если ваша цель состоит в том, чтобы «объединить» тела, вы можете просто определить тип внутри вашего шаблона функции:
template <char... C>
constexpr auto foo()
{
struct {
constexpr int operator()() {
char ch[] = { C... };
int count = 0;
for (char c : ch)
{
if (c != '0') count += 1;
}
return count;
};
} boo;
std::array<char, boo()> x{};
return x;
}
Если у вас есть C ++ 17,вы также можете использовать лямбда-выражения в константных выражениях, поэтому вы можете сократить boo
до:
constexpr auto boo = []() { /* ... */ };
В C ++ 20 вы сможете писать лямбда-выражения непосредственно в качестве аргумента шаблона, так что вы можетеуменьшите далее до (если вы действительно хотели бы):
std::array<char, []() { /* ... */ }()> x{};
Сказав это, в общем, я бы сказал, что обычный (и более чистый) подход имеет все виды дополнительныхкод, используемый шаблонами в заголовке, но не являющийся частью общедоступного интерфейса, помещает их в пространство имен detail
или с аналогичным именем:
namespace detail {
template <char... C>
constexpr int boo()
{
/* ... */
}
}
template <char... C>
constexpr auto foo()
{
/* ... detail::boo<C...>() ... */
}