4

This previously answered question explains why the code I have posted below does not work. I have a follow-up question: is there a workaround that is conceptually equivalent, i.e., achieves compile-time string concatenation, but is implemented in a way that is actually supported by C++11? Using std::string is completely non-essential.

constexpr std::string foo() { return std::string("foo"); }
constexpr std::string bar() { return std::string("bar"); }
constexpr std::string foobar() { return foo() + bar(); }
Community
  • 1
  • 1

2 Answers2

7

Compile-time "string" concatenation :

#include <iostream>
#include <string>

template <char ... CTail>
struct MetaString
{ 
    static std::string string()
    {
        return std::string{CTail...};
    }
};

template <class L, class R>
struct Concatenate;

template <char ... LC, char  ... RC>
struct Concatenate<MetaString<LC ... >, MetaString<RC ... >>
{
    typedef MetaString<LC ..., RC ... > Result;
};

int main()
{
    typedef MetaString<'f', 'o', 'o'> Foo;
    typedef MetaString<'b', 'a', 'r'> Bar;

    typedef typename Concatenate<Foo, Bar>::Result FooBar;

    std::cout << Foo::string() << std::endl; //  foo
    std::cout << Bar::string() << std::endl; //  bar
    std::cout << FooBar::string() << std::endl; //  foobar
}
Denis Kreshikhin
  • 8,856
  • 9
  • 52
  • 84
  • 1
    Is that actually going to work? I thought that you could only have one variadic pack. – Puppy Jan 30 '12 at 18:46
  • 4
    @DeadMG: You can have more than one if it can be deduced (function template) / is used in a partial specialization. Or in otherwords, if the pack itself isn't top-level. – Xeo Jan 31 '12 at 03:23
3

Sprout C++ Libraries provide constexpr string. see: https://github.com/bolero-MURAKAMI/Sprout/blob/master/libs/string/test/string.cpp

Daniel James
  • 3,899
  • 22
  • 30
Akira Takahashi
  • 2,912
  • 22
  • 107