It is possible to use itk::NumericTraits to get 0 and 1 of some type. Thus we can see this kind of code in the wild:
const PixelType ZERO = itk::NumericTraits<PixelType>::Zero;
const PixelType ONE = itk::NumericTraits<PixelType>::One;
This feels heavy and hard to read. As a programmer, I would prefer a more pragmatic version like:
const PixelType ZERO = 0;
const PixelType ONE = 1;
But is it entirely equivalent? I think the cast is done during the compilation so both versions should be identical in term of speed. If it's the case, why would anyone want to use itk::NumericTraits to get 0 and 1? There must be an advantage I'm not seeing.
Traits are typically used/useful in the context of generic programming. It's kind of heavily used in STL.
Lets consider your NumericTraits looks like below:
template <typename PixelT>
struct NumericTraits {
static const int ZERO = 0;
static const int ONE = 1;
};
In addition to this, you should or can constrain you template instance to a particular kind of type too..using enable_if et al.
Now, there comes a particular type of pixel which is special, how would you define ZERO and ONE for that ? Just specialize your NumericTraits
template <>
struct NumericTraits<SpecialPixel>{
static const int ZERO = 10;
static const int ONE = 20;
};
Got the idea and the usefulness? Now, another benefit of this is for converting value to type and then using it for tag dispatching:
void func(int some_val, std::true_type) {....}
void func(int some_val, std::false_type) {.....}
And call it like:
func(42, typename std::conditional<NumericTraits<PixelType>::ONE == 1, std::true_type, std::false_type>::type());
Which overload to call is decided at compile time here, relieving you from doing if - else checks and there by probably improving performance :)
Related
I'm writing a hashing function to help speed up string comparisons.
My codebase compares strings against a lot of const char[] constants, and it would be ideal if I could work with hashes instead. I went ahead and translated xxHash to modern C++, and I have a working prototype that does work at compile time, but I'm not sure what the function definition should be for the main hashing function.
At the moment, I have this:
template <size_t arr_size>
constexpr uint64_t xxHash64(const char(data)[arr_size])
{...}
This does work, and I am able to do a compile time call like this
constexpr char myString[] = "foobar";
constexpr uint64_t hashedString = xxHash64<sizeof myString>(myString);
[Find a minimal example here]
All good so far, but I would like to add a user-defined literal wrapper function for some eye candy, and this is where the problem lies.
UDLs come with a fixed prototype, as specified here
The Microsoft doc stipulates "Also, any of these operators can be defined as constexpr".
But when I try to call my hashing function from a constexpr UDL:
constexpr uint64_t operator "" _hashed(const char *arr, size_t size) {
return xxHash64<size>(arr);
}
function "xxHash64" cannot be called with the given argument list
argument types are: (const char*)
And the error does make sense. My function expects a character array, and instead it gets a pointer.
But if I were to modify the definition of my xxHash64 function to take a const char *, I can no longer work in a constexpr context because the compiler needs to resolve the pointer first, which happens at runtime.
So am I doing anything wrong here, or is this a limitation of UDLs or constexpr functions as a whole?
Again, I'm not 100% sure the templated definition at the top is the way to go, but I'm not sure how else I could read characters from a string at compile time.
I'm not limited by any compiler version or library. If there is a better way to do this, feel free to suggest.
there is no problem to call constexpr function with constexpr pointer as constant expression
constexpr uint64_t xxHash64(const char* s){return s[0];}
constexpr uint64_t operator "" _g(const char *arr,std::size_t){
return xxHash64(arr);
}
int main()
{
xxHash64("foo");
constexpr auto c = "foobar"_g;
return c;
}
would just work fine.
with c++20, you can also get the size as constant expression with string literal operator template.
#include <cstdint>
template <std::size_t arr_size>
constexpr std::uint64_t xxHash64(const char(&data)[arr_size]){
return data[0];
}
// template <std::size_t N> // can also be full class template (with CTAD)
struct hash_value{
std::uint64_t value;
template <std::size_t N>
constexpr hash_value(const char(&p)[N]):value(xxHash64(p)){}
};
template < hash_value v >
constexpr std::uint64_t operator ""_hashed() { return v.value; }
int main()
{
constexpr auto v = "foobar"_hashed;
return v;
}
I have such expressions in my code:
QByteArray idx0 = ...
unsigned short ushortIdx0;
if ( idx0.size() >= sizeof(ushortIdx0) ) {
// Do something
}
But I'm getting the warning:
warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
if ( idx0.size() >= sizeof(ushortIdx0) ) {
~~~~~~~~~~~~^~~~~~~~~~
Why size() of QByteArray is returned as int rather than unsigned int? How can I get rid of this warning safely?
Some folk feel that the introduction of unsigned types into C all those years ago was a bad idea. Such types found themselves introduced into C++, where they are deeply embedded in the C++ Standard Library and operator return types.
Yes, sizeof must, by the standard, return an unsigned type.
The Qt developers adopt the modern thinking that the unsigned types were a bad idea, and favour instead making the return type of size a signed type. Personally I find it idiosyncratic.
To solve, you could (i) live with the warning, (ii) switch it off for the duration of the function, or (iii) write something like
(std::size_t)idx0.size() >= sizeof(ushortIdx0)
at the expense of clarity.
Why size() of QByteArray is returned as int rather than unsigned int?
I literally have no idea why Qt chose a signed return for size(). However, there are good reasons to use a signed instead of an unsigned.
One infamous example where a unsigned size() fails miserably is this quite innocent looking loop:
for (int i = 0; i < some_container.size() - 1; ++i) {
do_somehting(some_container[i] , some_container[i+1] );
}
Its not too uncommon to make the loop body operate on two elements and in that case its seems to be a valid choice to iterate only till some_container.size() - 1.
However, if the container is empty some_container.size() - 1 will silently (unsigned overflow is well defined) turn into the biggest value for the unsigned type. Hence, instead of avoiding the out-of-bounds access it leads to the maximum out of bounds you can get.
Note that there are easy fixes for this problem, but if size() does return a signed value, then there is no issue that needs to be fixed in the first place.
Because in Qt containers (like: QByteArray, QVector, ...) there are functions which can return a negative number, like: indexOf, lastIndexOf, contains, ... and some can accept negative numbers, like: mid, ...; So to be class-compatible or even framework-compatibe, developers use a signed type (int).
You can use standard c++ casting:
if ( static_cast<size_t>(idx0.size()) >= sizeof(ushortIdx0) )
The reason why is a duplicate part of the question, but the solution to the type mismatch is a valid problem to solve. For the comparisons of the kind you're doing, it'd probably be useful to factor them out, as they have a certain reusable meaning:
template <typename T> bool fitsIn(const QByteArray &a) {
return static_cast<int>(sizeof(T)) <= a.size();
}
template <typename T> bool fitsIn(T, const QByteArray &a) {
return fitsIn<T>(a);
}
if (fitsIn(ushortIdx0, idx0)) ...
Hopefully you'll have just a few kinds of such comparisons, and it'd make most sense to DRY (do not repeat yourself) and instead of a copypasta of casts, use functions dedicated to the task - functions that also express the intent of the original comparison. It then becomes easy to centralize handling of any corner cases you might wish to handle, i.e. when sizeof(T) > INT_MAX.
Another approach would be to define a new type to wrap size_t and adapt it to the types you need to use it with:
class size_of {
size_t val;
template <typename T> static typename std::enable_if<std::is_signed<T>::value, size_t>::type fromSigned(T sVal) {
return (sVal > 0) ? static_cast<size_t>(sVal) : 0;
}
public:
template <typename T, typename U = std::enable_if<std::is_scalar<T>::value>::type>
size_of(const T&) : val(sizeof(T)) {}
size_of(const QByteArray &a) : val(fromSigned(a.size())) {}
...
bool operator>=(size_of o) const { return value >= o.value; }
};
if (size_of(idx0) >= size_of(ushortIdx0)) ...
This would conceptually extend sizeof and specialize it for comparison(s) and nothing else.
Is there anyway to do something like this?
(correct pointer datatype) returnPointer(void* ptr, int depth)
{
if(depth == 8)
return (uint8*)ptr;
else if (depth == 16)
return (uint16*)ptr;
else
return (uint32*)ptr;
}
Thanks
No. The return type of a C++ function can only vary based on explicit template parameters or the types of its arguments. It cannot vary based on the value of its arguments.
However, you can use various techniques to create a type that is the union of several other types. Unfortunately this won't necessarily help you here, as one such technique is void * itself, and getting back to the original type will be a pain.
However, by turning the problem inside out you may get what you want. I imagine you'd want to use the code you posted as something like, for example:
void bitmap_operation(void *data, int depth, int width, int height) {
some_magical_type p_pixels = returnPointer(data, depth);
for (int x = 0; x < width; x++)
for (int y = 0; y < width; y++)
p_pixels[y*width+x] = some_operation(p_pixels[y*width+x]);
}
Because C++ needs to know the type of p_pixels at compile time, this won't work as-is. But what we can do is make bitmap_operation itself be a template, then wrap it with a switch based on the depth:
template<typename PixelType>
void bitmap_operation_impl(void *data, int width, int height) {
PixelType *p_pixels = (PixelType *)data;
for (int x = 0; x < width; x++)
for (int y = 0; y < width; y++)
p_pixels[y*width+x] = some_operation(p_pixels[y*width+x]);
}
void bitmap_operation(void *data, int depth, int width, int height) {
if (depth == 8)
bitmap_operation_impl<uint8_t>(data, width, height);
else if (depth == 16)
bitmap_operation_impl<uint16_t>(data, width, height);
else if (depth == 32)
bitmap_operation_impl<uint32_t>(data, width, height);
else assert(!"Impossible depth!");
}
Now the compiler will automatically generate three implementations for bitmap_operation_impl for you.
If you can use a template argument instead of a normal parameter, you can create a templated function that returns the correct type for each depth value. First there needs to be some definition of the correct type according to depth. You can define a template with specializations for the different bit sizes:
// template declaration
template<int depth>
struct uint_tmpl;
// specializations for certain types
template<> struct uint_tmpl<8> { typedef uint8_t type; };
template<> struct uint_tmpl<16> { typedef uint16_t type; };
template<> struct uint_tmpl<32> { typedef uint32_t type; };
The this definition can be used to declare a templated function that returns the correct type for every bit value:
// generic declaration
template<int depth>
typename uint_tmpl<depth>::type* returnPointer(void* ptr);
// specializations for different depths
template<> uint8_t* returnPointer<8>(void* ptr) { return (uint8_t*)ptr; }
template<> uint16_t* returnPointer<16>(void* ptr) { return (uint16_t*)ptr; }
template<> uint32_t* returnPointer<32>(void* ptr) { return (uint32_t*)ptr; }
You can allocate some memory on the heap, and return a void* that you cast to the type that was allocated. Its a dangerous and unsafe way of working and is an old C trick.
You could return a union that contains all valid datatypes (and a selection indicator).
You could use templates, which is the recommended C++ way for this kind of thing.
You could provide a set of overloaded functions that take a parameter (of each type) as a reference - the compiler will decide which function to call based on the datatype. I often prefer this way as I think its the simplest.
No; you can't do that in C++. The correct answer is to return void *.
Think about it from the opposite side of the call -- and from the compiler point of view at that:
How would the compiler be able to verify if the return value is used correctly (like assigned to a variable of the proper type, for example), if it cannot possibly know which of the three return types will be returned?
At that point, the notion of assigning "one of multiple types" to the return value becomes meaningless. The return type of a function has no other purpose in life than to make it possible for the compiler to do it's job; the compiler needs "one" type to be able to do type checking. Since you don't know which one it is until runtime, the compiler can't do the type checking for you. You have to tell the compiler to "stop trying" to match the return value to any specific pointer type -- hence, return a void *.
If your depth arguments is known at compile time, you can alternatively use a set of templates like #sth demonstrated, or use a set of separate independent functions, or use a set of related functions that call a shared implementation function and then cast the return to the proper type. Which one you chose is a mostly an aesthetic decision.
If the value of depth is not know until run-time, then you should probably return void *.
Now, I'm assuming that your actual implementation actually does something to produce the pointer other than what your sample code shows. Your sample code is not an actual function; it's more like trying to duplicate what a cast does. A cast is not a function call; it's a compiler directive to try to "make" it's operand into a specific type (exactly 'how', is a long story for another post). It's not a C++ language operation, but a compiler operation. You can't rewrite that in C++ itself.
I'm wondering what the difference is between using a static const and an enum hack when using template metaprogramming techniques.
EX: (Fibonacci via TMP)
template< int n > struct TMPFib {
static const int val =
TMPFib< n-1 >::val + TMPFib< n-2 >::val;
};
template<> struct TMPFib< 1 > {
static const int val = 1;
};
template<> struct TMPFib< 0 > {
static const int val = 0;
};
vs.
template< int n > struct TMPFib {
enum {
val = TMPFib< n-1 >::val + TMPFib< n-2 >::val
};
};
template<> struct TMPFib< 1 > {
enum { val = 1 };
};
template<> struct TMPFib< 0 > {
enum { val = 0 };
};
Why use one over the other? I've read that the enum hack was used before static const was supported inside classes, but why use it now?
Enums aren't lvals, static member values are and if passed by reference the template will be instanciated:
void f(const int&);
f(TMPFib<1>::value);
If you want to do pure compile time calculations etc. this is an undesired side-effect.
The main historic difference is that enums also work for compilers where in-class-initialization of member values is not supported, this should be fixed in most compilers now.
There may also be differences in compilation speed between enum and static consts.
There are some details in the boost coding guidelines and an older thread in the boost archives regarding the subject.
For some the former one may seem less of a hack, and more natural. Also it has memory allocated for itself if you use the class, so you can for example take the address of val.
The latter is better supported by some older compilers.
On the flip side to #Georg's answer, when a structure that contains a static const variable is defined in a specialized template, it needs to be declared in source so the linker can find it and actually give it an address to be referenced by. This may unnecessarily(depending on desired effects) cause inelegant code, especially if you're trying to create a header only library. You could solve it by converting the values to functions that return the value, which could open up the templates to run-time info as well.
"enum hack" is a more constrained and close-enough to #define and that helps to initialise the enum once and it's not legal to take the address of an enum anywhere in the program and it's typically not legal to take the address of a #define, either. If you don't want to let people get a pointer or reference to one of your integral constants, an enum is a good way to enforce that constraint. To see how to implies to TMP is that during recursion, each instance will have its own copy of the enum { val = 1 } during recursion and each of those val will have proper place in it's loop. As #Kornel Kisielewicz mentioned "enum hack" also supported by older compilers those forbid the in-class specification of initial values to those static const.
Is there anyway to do something like this?
(correct pointer datatype) returnPointer(void* ptr, int depth)
{
if(depth == 8)
return (uint8*)ptr;
else if (depth == 16)
return (uint16*)ptr;
else
return (uint32*)ptr;
}
Thanks
No. The return type of a C++ function can only vary based on explicit template parameters or the types of its arguments. It cannot vary based on the value of its arguments.
However, you can use various techniques to create a type that is the union of several other types. Unfortunately this won't necessarily help you here, as one such technique is void * itself, and getting back to the original type will be a pain.
However, by turning the problem inside out you may get what you want. I imagine you'd want to use the code you posted as something like, for example:
void bitmap_operation(void *data, int depth, int width, int height) {
some_magical_type p_pixels = returnPointer(data, depth);
for (int x = 0; x < width; x++)
for (int y = 0; y < width; y++)
p_pixels[y*width+x] = some_operation(p_pixels[y*width+x]);
}
Because C++ needs to know the type of p_pixels at compile time, this won't work as-is. But what we can do is make bitmap_operation itself be a template, then wrap it with a switch based on the depth:
template<typename PixelType>
void bitmap_operation_impl(void *data, int width, int height) {
PixelType *p_pixels = (PixelType *)data;
for (int x = 0; x < width; x++)
for (int y = 0; y < width; y++)
p_pixels[y*width+x] = some_operation(p_pixels[y*width+x]);
}
void bitmap_operation(void *data, int depth, int width, int height) {
if (depth == 8)
bitmap_operation_impl<uint8_t>(data, width, height);
else if (depth == 16)
bitmap_operation_impl<uint16_t>(data, width, height);
else if (depth == 32)
bitmap_operation_impl<uint32_t>(data, width, height);
else assert(!"Impossible depth!");
}
Now the compiler will automatically generate three implementations for bitmap_operation_impl for you.
If you can use a template argument instead of a normal parameter, you can create a templated function that returns the correct type for each depth value. First there needs to be some definition of the correct type according to depth. You can define a template with specializations for the different bit sizes:
// template declaration
template<int depth>
struct uint_tmpl;
// specializations for certain types
template<> struct uint_tmpl<8> { typedef uint8_t type; };
template<> struct uint_tmpl<16> { typedef uint16_t type; };
template<> struct uint_tmpl<32> { typedef uint32_t type; };
The this definition can be used to declare a templated function that returns the correct type for every bit value:
// generic declaration
template<int depth>
typename uint_tmpl<depth>::type* returnPointer(void* ptr);
// specializations for different depths
template<> uint8_t* returnPointer<8>(void* ptr) { return (uint8_t*)ptr; }
template<> uint16_t* returnPointer<16>(void* ptr) { return (uint16_t*)ptr; }
template<> uint32_t* returnPointer<32>(void* ptr) { return (uint32_t*)ptr; }
You can allocate some memory on the heap, and return a void* that you cast to the type that was allocated. Its a dangerous and unsafe way of working and is an old C trick.
You could return a union that contains all valid datatypes (and a selection indicator).
You could use templates, which is the recommended C++ way for this kind of thing.
You could provide a set of overloaded functions that take a parameter (of each type) as a reference - the compiler will decide which function to call based on the datatype. I often prefer this way as I think its the simplest.
No; you can't do that in C++. The correct answer is to return void *.
Think about it from the opposite side of the call -- and from the compiler point of view at that:
How would the compiler be able to verify if the return value is used correctly (like assigned to a variable of the proper type, for example), if it cannot possibly know which of the three return types will be returned?
At that point, the notion of assigning "one of multiple types" to the return value becomes meaningless. The return type of a function has no other purpose in life than to make it possible for the compiler to do it's job; the compiler needs "one" type to be able to do type checking. Since you don't know which one it is until runtime, the compiler can't do the type checking for you. You have to tell the compiler to "stop trying" to match the return value to any specific pointer type -- hence, return a void *.
If your depth arguments is known at compile time, you can alternatively use a set of templates like #sth demonstrated, or use a set of separate independent functions, or use a set of related functions that call a shared implementation function and then cast the return to the proper type. Which one you chose is a mostly an aesthetic decision.
If the value of depth is not know until run-time, then you should probably return void *.
Now, I'm assuming that your actual implementation actually does something to produce the pointer other than what your sample code shows. Your sample code is not an actual function; it's more like trying to duplicate what a cast does. A cast is not a function call; it's a compiler directive to try to "make" it's operand into a specific type (exactly 'how', is a long story for another post). It's not a C++ language operation, but a compiler operation. You can't rewrite that in C++ itself.