Pup*_*ppy 28 c++ string templates
为什么你不能在这里传递文字字符串?我使用了一个非常轻微的解决方法.
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();
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*itb 16
因为这不是一个有用的实用程序.由于它们不是模板参数的允许形式,因此它目前不起作用.
让我们假设它们有效.因为它们不需要对所使用的相同值具有相同的地址,所以即使在代码中具有相同的字符串文字值,也将获得不同的实例化.
lols<"A"> n;
// might fail because a different object address is passed as argument!
lols<"A"> n1 = n;
Run Code Online (Sandbox Code Playgroud)
您可以为文本编辑器编写一个插件,用逗号分隔的字符文字列表替换字符串.使用可变参数模板,您可以通过某种方式以这种方式"解决"该问题.
这是可能的,但模板参数必须具有外部链接,这排除了使用文字字符串并减轻了执行此操作的效用.
我的一个例子是:
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_>();
Run Code Online (Sandbox Code Playgroud)
我就是这样做的.对我来说更有意义:
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>();
}
Run Code Online (Sandbox Code Playgroud)
好问题,我想我应该投身其中......我想你可以将指向静态变量的指针作为非类型模板参数传递。从 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;
}
Run Code Online (Sandbox Code Playgroud)
我最近很少使用 C++,所以如果这不是 100% 正确,我很抱歉。有评论说为什么这在 c++20 中不会成为问题。根据template_parameters的参考:
非类型模板参数必须具有结构类型,该类型是以下类型之一(可选 cv 限定,限定符被忽略):
...
- 浮点类型;
- 具有以下属性的文字类类型:
- 所有基类和非静态数据成员都是公共且不可变的
- 所有基类和非静态数据成员的类型都是结构类型或其(可能是多维)数组。
这让我相信以下代码可以工作:
struct conststr
{
const char * const p;
template<std::size_t N>
constexpr conststr(const char(&a)[N]) : p(a)/*, sz(N - 1) */{}
};
template<conststr s>
struct A{};
int main(int argc, char **argv) {
A<conststr("foo")> x;
}
Run Code Online (Sandbox Code Playgroud)
(再次强调,我不能 100% 确定这是否 100% 正确)。但事实并非如此,至少在我的机器上没有g++ -std=c++2a
(g++ --version == g++ (Debian 8.3.0-6) 8.3.0
)。它也不起作用double
。 这个人在这里对历史进行了更详细的描述,并且可能有更好的参考资料,而且我可能完全错误。