为什么你不能在这里传递文字字符串?我使用了一个非常轻微的解决方法。
template<const char* ptr> struct lols {
lols() : i(ptr) {}
std::string i;
};
class file {
public:
static const char arg[];
};
decltype(file::arg) file::arg = __FILE__;
// Getting the right type declaration for this was irritating, so I C++0xed it.
int main() {
// lols<__FILE__> hi;
// Error: A template argument may not reference a non-external entity
lols<file::arg> hi; // Perfectly legal
std::cout << hi.i;
std::cin.ignore();
std::cin.get();
}
答案 0 :(得分:16)
因为这不是一个有用的实用程序。由于它们不是模板参数的允许形式,因此它目前不起作用。
让我们假设他们有效。因为它们不需要对所使用的相同值具有相同的地址,所以即使在代码中具有相同的字符串文字值,也将获得不同的实例化。
lols<"A"> n;
// might fail because a different object address is passed as argument!
lols<"A"> n1 = n;
您可以为文本编辑器编写一个插件,用逗号分隔的字符文字列表替换字符串。使用可变参数模板,您可以通过某种方式“解决”这个问题。
答案 1 :(得分:6)
这是可能的,但模板参数必须具有外部链接,这排除了使用文字字符串并减轻了执行此操作的效用。
我的一个例子是:
template<const char* name, const char* def_value=empty_>
struct env : public std::string
{
env()
{
const char* p = std::getenv(name);
assign(p ? p : def_value);
}
};
extern const char empty_[] = "";
std::string test = env<empty_>();
答案 2 :(得分:5)
我就是这样做的。对我来说更有意义:
struct MyString { static const std::string val; }
const std::string MyString::val = "this is your string";
template<typename T>
void func()
{
std::cout << T::val << std::endl;
}
void main()
{
func<MyString>();
}
答案 3 :(得分:1)
这适用于类,IMO非常有用。实施快速而肮脏,但可以很容易变得更干净:
#include <stdio.h>
#include <string.h>
struct TextTag { const char *text; };
template <const TextTag &TRUE, const TextTag &FALSE>
struct TextTaggedBool
{
const char *GetAsText() const { return m_value ? TRUE.text: FALSE.text; }
void SetByText(const char *s) { m_value = !strcmp(s, TRUE.text); }
bool m_value;
};
class Foo
{
public:
void method()
{
m_tbool.SetByText("True!"); printf("%s\n", m_tbool.GetAsText());
m_tbool.SetByText("False!"); printf("%s\n", m_tbool.GetAsText());
m_tbool.m_value = true; printf("%s\n", m_tbool.GetAsText());
m_tbool.m_value = false; printf("%s\n", m_tbool.GetAsText());
}
private:
static constexpr TextTag TrueTag = { "True!" };
static constexpr TextTag FalseTag = { "False!" };
TextTaggedBool<TrueTag, FalseTag> m_tbool;
};
void main() { Foo().method(); }
输出:
真! 假! 真正! 假的!
答案 4 :(得分:0)
很好的问题,以为我会戴上帽子……我想您可以将指向静态变量的指针作为非类型模板参数传递。从C ++ 20看来,这将不再是问题...在此之前,这里有一些廉价的宏可以使其正常工作。
template <const char *Name, typename T>
struct TaggedValue {
static constexpr char const *name{Name};
T value;
friend ostream &operator<<(ostream &o, const TaggedValue &a) {
return o << a.name << " = " << a.value;
}
};
#define ST(name, type)\
const char ST_name_##name[]{#name};\
using name = TaggedValue<ST_name_##name,type>;
ST(Foo, int);
ST(Bar, int);
ST(Bax, string);
int main() {
cout << Foo{3} << endl;
cout << Bar{5} << endl;
cout << Bax{"somthing"} << endl;
}