Definition Of Struct Template Value In Constructor / Member Function
I'm working with a Pascal library that uses UCSD Strings. I created this template struct for making working with them easier:
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");
I know it does not cover WideChar cases but the library does neither in the first place so I'm safe in that regard.
Anyway, my problem is that I don't want to use a macro and instead would like to create a constructor. So I was wondering if does C++ offers a possibility of implementing something like this pseudocode:
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");
Of course, it does not need to be a "constructor". It is just an example.
I also tried this:
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");
But that in itself represents another issue. Because now I cannot reference the static function from DString without doing DString< size >::build(...);
.
What can I do in this case?
Answer
If you can use at least C++17... using a delegate constructor and CTAD...
You can add in DString
an additional template constructor (maybe private
), otherwise you can't initialize, directly, a char[]
with a char const *
template <std::size_t ... Is>
DString (std::index_sequence<Is...>, char const * s, unsigned r)
: Reference{r}, Size{N}, String{ s[Is]... }
{ }
Next you have to call the new constructor from the old one
DString (char const * s, unsigned r = 0x0FFFFFFFFu):
DString(std::make_index_sequence<N>{}, s, r)
{ }
Last, you have to add an explicit deduction guide (given that you want a DString<3>
from a char const [4]
template <std::size_t N>
DString (char const (&)[N], unsigned = 0u) -> DString<N-1u>;
and the automatic deduction works.
The following is a full compiling example
#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"};
}
Related Questions
- → Comparing two large files are taking over four hours
- → Setting JSON node name to variable value
- → Compiling GLUT using Emscripten
- → Evaluate check box from a scanned image in node.js
- → Find an easy web server framework for mobile game
- → my https C++ code doesn't work on some sites (binance)
- → Error while opening pivx wallet on ubuntu
- → Why sending a POST by AJAX is interpreted by the HTTP Server as OPTIONS and sending by CURL is effectively a PUT?
- → Python reading in one line multiple types for a calculator
- → How do I properly pass an argument to a function
- → Accessing Websql database with Qt
- → Using Mysql C API for c++ codes
- → How do I set constants at run-time in a c++ header file, imported through Cython?