在构造函数/成员函数中定义结构模板值
Definition of struct template value in constructor / member function
我正在使用使用 UCSD 字符串的 Pascal 库。我创建了这个模板结构,以便更轻松地使用它们:
template <std::size_t N>
struct DString {
unsigned Reference, Size = N;
char String[N];
};
#define MAKE_STRING(X) DString<sizeof(X)>{ 0x0FFFFFFFF, sizeof(X) - 1, X}
auto foo = MAKE_STRING("Foo");
我知道它不包括 WideChar 案例,但图书馆一开始就没有,所以我在这方面是安全的。
无论如何,我的问题是我不想使用宏,而是想创建一个构造函数。所以我想知道 C++ 是否提供了实现类似伪代码的可能性:
template <std::size_t N>
struct DString {
unsigned Reference, Size = N;
char String[N];
DString<sizeof(s)>(const char* s, unsigned r = 0x0FFFFFFFF):
String(s), Reference(r) {}
};
auto foo = DString("Foo");
当然,也不一定是“构造函数”。这只是一个例子。
我也试过这个:
template <std::size_t N>
struct DString {
unsigned Reference, Size = N;
char String[N];
inline static DString build(const char* X) {
return DString<sizeof(X)>{ 0x0FFFFFFFF, sizeof(X) - 1, X};
}
};
auto foo = DString::build("Foo");
但这本身代表了另一个问题。因为现在我无法在不执行 DString< size >::build(...);
.
的情况下从 DString 引用静态函数
遇到这种情况我该怎么办?
如果您至少可以使用 C++17...使用委托构造函数和 CTAD...
您可以在 DString
中添加一个额外的模板构造函数(可能是 private
),否则您无法直接初始化 char[]
和 char const *
template <std::size_t ... Is>
DString (std::index_sequence<Is...>, char const * s, unsigned r)
: Reference{r}, Size{N}, String{ s[Is]... }
{ }
接下来你必须从旧的构造函数中调用新的构造函数
DString (char const * s, unsigned r = 0x0FFFFFFFFu):
DString(std::make_index_sequence<N>{}, s, r)
{ }
最后,您必须添加一个明确的推导指南(假设您想要 DString<3>
来自 char const [4]
template <std::size_t N>
DString (char const (&)[N], unsigned = 0u) -> DString<N-1u>;
并且自动扣除有效。
下面是一个完整的编译示例
#include <utility>
#include <iostream>
template <std::size_t N>
struct DString {
private:
template <std::size_t ... Is>
DString (std::index_sequence<Is...>, char const * s, unsigned r)
: Reference{r}, Size{N}, String{ s[Is]... }
{ }
public:
unsigned Reference, Size = N;
char String[N];
DString (char const * s, unsigned r = 0x0FFFFFFFFu):
DString(std::make_index_sequence<N>{}, s, r)
{ }
};
template <std::size_t N>
DString (char const (&)[N], unsigned = 0u) -> DString<N-1u>;
int main()
{
auto foo = DString{"Foo"};
}
我正在使用使用 UCSD 字符串的 Pascal 库。我创建了这个模板结构,以便更轻松地使用它们:
template <std::size_t N>
struct DString {
unsigned Reference, Size = N;
char String[N];
};
#define MAKE_STRING(X) DString<sizeof(X)>{ 0x0FFFFFFFF, sizeof(X) - 1, X}
auto foo = MAKE_STRING("Foo");
我知道它不包括 WideChar 案例,但图书馆一开始就没有,所以我在这方面是安全的。
无论如何,我的问题是我不想使用宏,而是想创建一个构造函数。所以我想知道 C++ 是否提供了实现类似伪代码的可能性:
template <std::size_t N>
struct DString {
unsigned Reference, Size = N;
char String[N];
DString<sizeof(s)>(const char* s, unsigned r = 0x0FFFFFFFF):
String(s), Reference(r) {}
};
auto foo = DString("Foo");
当然,也不一定是“构造函数”。这只是一个例子。
我也试过这个:
template <std::size_t N>
struct DString {
unsigned Reference, Size = N;
char String[N];
inline static DString build(const char* X) {
return DString<sizeof(X)>{ 0x0FFFFFFFF, sizeof(X) - 1, X};
}
};
auto foo = DString::build("Foo");
但这本身代表了另一个问题。因为现在我无法在不执行 DString< size >::build(...);
.
遇到这种情况我该怎么办?
如果您至少可以使用 C++17...使用委托构造函数和 CTAD...
您可以在 DString
中添加一个额外的模板构造函数(可能是 private
),否则您无法直接初始化 char[]
和 char const *
template <std::size_t ... Is>
DString (std::index_sequence<Is...>, char const * s, unsigned r)
: Reference{r}, Size{N}, String{ s[Is]... }
{ }
接下来你必须从旧的构造函数中调用新的构造函数
DString (char const * s, unsigned r = 0x0FFFFFFFFu):
DString(std::make_index_sequence<N>{}, s, r)
{ }
最后,您必须添加一个明确的推导指南(假设您想要 DString<3>
来自 char const [4]
template <std::size_t N>
DString (char const (&)[N], unsigned = 0u) -> DString<N-1u>;
并且自动扣除有效。
下面是一个完整的编译示例
#include <utility>
#include <iostream>
template <std::size_t N>
struct DString {
private:
template <std::size_t ... Is>
DString (std::index_sequence<Is...>, char const * s, unsigned r)
: Reference{r}, Size{N}, String{ s[Is]... }
{ }
public:
unsigned Reference, Size = N;
char String[N];
DString (char const * s, unsigned r = 0x0FFFFFFFFu):
DString(std::make_index_sequence<N>{}, s, r)
{ }
};
template <std::size_t N>
DString (char const (&)[N], unsigned = 0u) -> DString<N-1u>;
int main()
{
auto foo = DString{"Foo"};
}