Trying to pass string literals as template arguments
c++, c++11, literals, string, templates
Solution
re: your OP: `I'd like to know why a couple of them failed.`
The comment by @NatanReed is correct:
- Your first snippet fails because `Get` needs a `TYPE` and is given an `object`.
- Your second snippet fails because it is illegal to define a template argument as reference to an object.
- until C++2003, that is. Then `reference to an object` became legal.
Template arguments must be constants from a limited set of types.
- See: ISO/IEC 14882-2003 §14.1: Template parameters
- See: ISO/IEC 14882-2003 §14.3.2: Template non-type arguments
And even then, the `String constexpr str = "hello";` must have external linkage. So putting it on the stack inside of `main()` is not going to work.
Give this a try:
#include <iostream>
#include <string>
using namespace std;
struct String {
char const *m_sz;
constexpr String(char const *a_sz)
:
m_sz(a_sz) {}
};
template<String const &_rstr>
string const Get() {
return _rstr.m_sz;
}
extern String constexpr globally_visible_str = "hello";
int main() {
cout << Get<globally_visible_str>() << endl;
return 0;
}
Problem
I'm trying to find a comfortable way to pass string literals as template arguments. I'm not caring about supporting the widest possible number of compilers, I'm using the latest version of g++ with `--std=c++0x`. I've tried a lot of possible solutions but all have disappointed me. I'm sort of giving up, but first I'd like to know why a couple of them failed. Here they are: ``` #include <iostream> #include <string> using namespace std; struct String { char const *m_sz; constexpr String(char const *a_sz) : m_sz(a_sz) {} char const *operator () () const { return m_sz; } }; template<class _rstr> string const Get() { return _rstr(); } int main() { cout << Get<String("hello")>() << endl; return 0; } ``` And: ``` #include <iostream> #include <string> using namespace std; struct String { char const *m_sz; constexpr String(char const *a_sz) : m_sz(a_sz) {} }; template<String const &_rstr> string const Get() { return _rstr.m_sz; } int main() { String constexpr str = "hello"; cout << Get<str>() << endl; return 0; } ``` The goal was to find a comfortable way to pass a string literal to the useless Get function, which returns its template argument as an std::string object. EDIT: sorry, maybe my main question isn't clear. My question is: why do those two snippets fail?