Cannot use integers in template parameters due to private data members.
xamidi opened this issue · 6 comments
According to README.md
:
- Signed and unsigned versions of
uintwide_t
should behave as closely as possible to the behaviors of signed and unsigned versions of built-inint
.
So I tried to use math::wide_integer::uint256_t
as a template parameter, but it failed with an error
'math::wide_integer::uintwide_t<256, unsigned int>' is not a valid type for a template non-type parameter because it is not structural
Fix:
This seems to be caused by the existence of non-public data members.
In math/wide_integer/uintwide_t.h
I replaced all private:
by public:
, and now it works.
Code example:
#include <cstdint>
#include <iostream>
#include "wide-integer/uintwide_t.h"
template<typename UInt, uint32_t B = 8 * sizeof(UInt), UInt MAX = -UInt(1)> void f(uint32_t n) {
std::cout << B << "-bit ; MAX = " << MAX << ", n = " << UInt(n) << std::endl;
}
int main() {
f<math::wide_integer::uint256_t>(42); // prints "256-bit ; MAX = 115792089237316195423570985008687907853269984665640564039457584007913129639935, n = 42"
}
Apart from that, great work! sizeof(UInt)
and -UInt(1)
wouldn't even work with the types of Boost.Multiprecision, and UInt(-1)
refused to be constexpr
. All these things work fine with uintwide_t
.
... tried to use
math::wide_integer::uint256_t
as a template parameter, but it failed with an error ...
... the existence of non-public data members
Thank you for your query. I must admit, I have never tried this exact kind of templatization. Please allow me to take a look at a few options regarding compatibility and get back to your query shortly.
I would not immediately want to make the private data members public, but we might consider doing this with a new, specific compiler switch.
Anyway, please allow me to investigate your query a bit. i'll get back with suggestions...
Kind regards, Chris
Proposed solution:
#define WIDE_INTEGER_DISABLE_PRIVATE_CLASS_DATA_MEMBERS
This optional macro can be used to disable uintwide_t
's private data members and make them public. This allows the uintwide_t
class to be used as a structured class object, such as is needed for constant-valued template parameters in the sense of C++20's constexpr
-ness.
Making private data members public is unusual for some designs so the default value is WIDE_INTEGER_DISABLE_PRIVATE_CLASS_DATA_MEMBERS
disabled and uintwide_t
's data members remain private.
The repair is cycling in CI.
Cc: @xamidi
Thank you for the quick fix. I switched to the original file already, and all seems good. :)
Thank you for the quick fix. I switched to the original file already, and all seems good.
Great! Thank you @xamidi for raising this interesting issue. Glad it works.
If you encounter anything else or have future ideas, please feel free to stop by.