-1

In C with #define it's easy to concatenates two strings for example:
#define PRINT_DBG(_msg_) print("[DBG]" _msg_)

I was looking and found this exist conststr
Is it possible to link this literals at compile time?

 template<typename... Args>
 inline void DBG(conststr fmt, Args... args)
 {
     printf ("[DBG]" fmt,  args ...);
 } 

 template<typename... Args>
 inline void WRN(conststr fmt, Args... args)
 {
     printf (""\e[1;31m" [WRN]" fmt + "\e[0m",  args ...);
 } 

As first arg function take const char *. Any idea?

I found also this implementation, but seems to not work also. https://github.com/akrzemi1/static_string

Purpose:

Example of use. I want to make it work on compile time. For now i use makro for this purpose.

DBG("Some dbg information %s", "23");
WRN("Some wrn information %s", "44");
S.R
  • 2,411
  • 1
  • 22
  • 33
  • 1
    conststr (bad link btw.)? Did you mean `constexpr`? Perhaps [this](https://msdn.microsoft.com/en-us/magazine/dn973010.aspx) article may be useful? – Paul Rooney Sep 22 '17 at 10:43
  • 1
    http://en.cppreference.com/w/cpp/concept/LiteralType ? – Jarod42 Sep 22 '17 at 10:51
  • 1
    it is not clear what you are trying to achieve. Please add a usage and the expected behavior. – bolov Sep 22 '17 at 11:02
  • What's `function` and why can you not have a comma in `function ("[DBG]", fmt,`? – Bo Persson Sep 22 '17 at 11:08
  • @bolov I updated question with simple pseudo code example. – S.R Sep 22 '17 at 11:12
  • @BoPersson If there will be many threads printing at standard io there is no guarantee to calls `print("[DBG]")` `printf("fmt %s", "s")` `print("\n")` will be outputed at once. I would have to add some `lockf`. I would prefer to link this constexpresion string at compile time. But i guess it's impossible without macro. – S.R Sep 22 '17 at 11:17
  • @S.R if this is meant to be used in a multithreaded env., then you must use some sort of synchronization mechanism. You can't go around that as `printf` is not thread-safe. – bolov Sep 22 '17 at 11:23
  • See [this](https://stackoverflow.com/questions/13292237/c-concat-two-const-char-string-literals) and [this](https://akrzemi1.wordpress.com/2017/06/28/compile-time-string-concatenation/) – NathanOliver Sep 22 '17 at 11:40

2 Answers2

0
template<typename... Args>
void dbg(const std::string& fmt, Args... args)
{
    using namespace std::string_literals;
    printf ("[DBG]"s + fmt,  args ...);
} 

printf is not a constexpr function so it makes no sense to want constexpr here, although I am not entirely sure what you mean by that.

So the simple answer is to just use the standard std::string concatenation: the overloaded + operator.

bolov
  • 72,283
  • 15
  • 145
  • 224
  • I was looking for in place inserting at compile time. To printf should go just pointer to a string that was concatenates at compile time. I will use preproseor. – S.R Sep 22 '17 at 11:33
  • @S.R why? What is the reason and motivation behind this requirement? – bolov Sep 22 '17 at 11:37
  • Really quick logging library. With easy pre and post syntax. But I founding more and more complications. So probably my idea is just wrong. – S.R Sep 22 '17 at 11:42
  • 1
    you are doing premature optimizations. That is bad. Focus on functionality and clear code. And then the right way to reach the "quick" part is to **profile** and optimize. Not the other way around. Don't try to optimize parts of the code you don't know they need optimization. My strong advice: do simple normal `std::string` concatenation. – bolov Sep 22 '17 at 11:45
  • Thanks for advice. But you have to allow make me mistakes.. Without it I will learn nothing. If I don't understand why i will be always misleading. – S.R Sep 22 '17 at 11:55
0

Maybe you can use this gnu extension for templated user defined string literals, if you are working with gcc or clang. clang will warn for using the gnu extension but will generate the compile time string also.

template < class T, T... Chrs>
struct mystring
{   
    static auto c_str()
    {
        static char str[] = {Chrs..., 0}; 
        return str;
    }

    template < T... in> 
    constexpr auto operator+( mystring<T,in...>  )
    {

        return mystring< T, Chrs..., in...>{};
    }
};  




template <class T, T... Chrs>
auto operator""_s()
{   
    return mystring<T, Chrs...>{};
}   

auto x = "That "_s+"is "_s + " my "_s + " string!"_s;


int main()
{   
    std::cout << x.c_str() << std::endl;
}   

The executable contains the string in its data section, so you see it was generated at compile time:

[krud@localhost ~]$ objdump -s -j .data go

go:     file format elf64-x86-64

Contents of section .data:
  601050 00000000 00000000 00000000 00000000  ................
  601060 54686174 20697320 206d7920 20737472  That is  my  str
  601070 696e6721 00                          ing!.  "
Klaus
  • 24,205
  • 7
  • 58
  • 113