sizeof in variadic template c++ - c++
I need to know how many items in parameter pack of a variadic templete.
my code:
#include <iostream>
using namespace std;
template <int... Entries>
struct StaticArray
{
int size = sizeof... (Entries);// line A
//int array[size] = {Entries...};// line B
};
int main()
{
StaticArray<1,2,3,4> sa;
cout << sa.size << endl;
return 0;
}
I got compilation error on line A.
if change this line to
static const unsigned short int size = sizeof...(Arguments)
It can be compiled. my first question is why I need "static const unsigned short" to get compiled.
as you can see, I need a size to put in on my array. my final goal is able to print this array out in main function.
please help. thanks..
my ideal comes from this website but i dont know how to make it works
http://thenewcpp.wordpress.com/2011/11/23/variadic-templates-part-1-2/
As per the comments, I think this is a bug in g++'s handling of the new in-class initialisation of member variables. If you change the code to
template <int... Entries>
struct StaticArray
{
static const int size = sizeof...(Entries); // works fine
};
then it works correctly, because this uses the C++03 special case of initialising static const integral members in-class.
Similarly, if you use the new C++11 uniform initialisation syntax, it works correctly:
template <int... Entries>
struct StaticArray
{
int size{sizeof...(Entries)}; // no problem
};
I'm pretty sure the assignment form is valid here, so I think g++ (4.8.2 on my system) is getting it wrong.
(Of course, the size can't change at run-time, so the correct declaration would probably be static constexpr std::size_t size anyway, avoiding this problem...)
Related
What is the proper definition for a constexpr function that take a character array?
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; }
Get size of an array-pointer template parameter
I wondered if I could auto deduce the size of an array, which is passed as a template parameter, without (explicitly) passing its size. The following code both compiles warning-less on g++ 4.8 and clang++ 3.3 (using -std=c++11 -Wall). #include <iostream> template<const int* arr> struct array_container { static constexpr int val = arr[1]; array_container() { std::cout << val << std::endl; } // static constexpr int arr_size = ??; }; constexpr int one[] = { 1 }; constexpr int two[] = { 1, 2 }; int main() { // array_container<one> array_one; array_container<two> array_two; // (void) array_one; (void) array_two; return 0; } However, if I remove the two comment signs in main(), I get an out of bound error with both compilers. Now, this is cool. Somehow the compiler knows the size of the array, though the type of const int* arr is a pointer. Is there any way to get the size of arr, e.g. to complete my comment in array_container? Of course, you are not allowed to Use any macros Store the size in arr (e.g. passing an std::array as template parameter: constexpr std::array<int, 1> one = { 1 }, or using an end marker like '\0' in strings) Use an additional template parameter for the size that can not be auto deduced (array_container<1, one> array_one).
Maybe std::extent template from <type_traits> header of C++11 standard library is what you want: #include <iostream> #include <type_traits> constexpr int one[] = { 1 }; constexpr int two[] = { 1, 2 }; int main() { std::cout << std::extent<decltype(one)>::value << std::endl; std::cout << std::extent<decltype(two)>::value << std::endl; return 0; } Output: 1 2
template<size_t size> constexpr size_t arraySize ( const int ( &arrayRef ) [size] ) { return size; } int main(){ int A[1]; int B[2]; cout << arraySize(A) << arraySize(B); return 0; } I believe something like this is what you're looking for, using array references. The syntax for declaring an array reference looks kind of like the syntax for a function pointer. This function template accepts an array reference named arrayRef, which prevents array-to-pointer decay so that compile-time info about array size is preserved. As you can see, the template argument is implicit to the compiler. Note that this can only work when the size can be deduced at compile time. Interestingly, this should still work without naming arrayRef at all. To make the above template more useful, you can add a template parameter to deduce the type of the array as well. I left it out for clarity.
Probably not, as SFINAE only happens in the immediate context, while that error comes from the requirement that UB in constexpr lead to a compile time error, which I think is not immediate. You could try a recursive SFINAE that stops on the UB, but even if it worked you would have to both check the standard and hope it does not change (as it is rather obscure and new). The easy way is to ise s function to deduce the array size, have to explicitly pass it to the type, then store it in an auto. Probably not what you want. There are proposals to allow type parameters to be deduced from value parameters, so you could wait for those instead. Not a solid answer, more of an extended comment, so marked community wiki.
It is indeed possible. I found a solution using SFINAE. What it basically does is produce a substitution error if the index is out of bound (line 3 in this example): template<class C> static yes& sfinae(typename val_to_type< decltype(*C::cont::data), *(C::cont::data + C::pos)>::type ); template<class C> static no& sfinae(C ); The full source code is on github. There are only two disadvantages: You have to specify the type of the array (this can not be avoided) It only works with g++ 4.8.1 and clang 3.3. g++ fails for empty strings (with a compiler bug). If someone can test for other compilers, that would be appreciated.
What is a common C/C++ macro to determine the size of a structure member?
In C/C++, how do I determine the size of the member variable to a structure without needing to define a dummy variable of that structure type? Here's an example of how to do it wrong, but shows the intent: typedef struct myStruct { int x[10]; int y; } myStruct_t; const size_t sizeof_MyStruct_x = sizeof(myStruct_t.x); // error For reference, this should be how to find the size of 'x' if you first define a dummy variable: myStruct_t dummyStructVar; const size_t sizeof_MyStruct_x = sizeof(dummyStructVar.x); However, I'm hoping to avoid having to create a dummy variable just to get the size of 'x'. I think there's a clever way to recast 0 as a myStruct_t to help find the size of member variable 'x', but it's been long enough that I've forgotten the details, and can't seem to get a good Google search on this. Do you know? Thanks!
In C++ (which is what the tags say), your "dummy variable" code can be replaced with: sizeof myStruct_t().x; No myStruct_t object will be created: the compiler only works out the static type of sizeof's operand, it doesn't execute the expression. This works in C, and in C++ is better because it also works for classes without an accessible no-args constructor: sizeof ((myStruct_t *)0)->x
I'm using following macro: #include <iostream> #define DIM_FIELD(struct_type, field) (sizeof( ((struct_type*)0)->field )) int main() { struct ABC { int a; char b; double c; }; std::cout << "ABC::a=" << DIM_FIELD(ABC, a) << " ABC::c=" << DIM_FIELD(ABC, c) << std::endl; return 0; } Trick is treating 0 as pointer to your struct. This is resolved at compile time so it safe.
You can easily do sizeof(myStruct().x) As sizeof parameter is never executed, you'll not really create that object.
Any of these should work: sizeof(myStruct_t().x;); or myStruct_t *tempPtr = NULL; sizeof(tempPtr->x) or sizeof(((myStruct_t *)NULL)->x); Because sizeof is evaluated at compile-time, not run-time, you won't have a problem dereferencing a NULL pointer.
In C++11, this can be done with sizeof(myStruct_t::x). C++11 also adds std::declval, which can be used for this (among other things): #include <utility> typedef struct myStruct { int x[10]; int y; } myStruct_t; const std::size_t sizeof_MyStruct_x_normal = sizeof(myStruct_t::x); const std::size_t sizeof_MyStruct_x_declval = sizeof(std::declval<myStruct_t>().x);
From my utility macros header: #define FIELD_SIZE(type, field) (sizeof(((type *)0)->field)) invoked like so: FIELD_SIZE(myStruct_t, x);
Compile time sizeof_array without using a macro
This is just something that has bothered me for the last couple of days, I don't think it's possible to solve but I've seen template magic before. Here goes: To get the number of elements in a standard C++ array I could use either a macro (1), or a typesafe inline function (2): (1) #define sizeof_array(ARRAY) (sizeof(ARRAY)/sizeof(ARRAY[0])) (2) template <typename T> size_t sizeof_array(const T& ARRAY){ return (sizeof(ARRAY)/sizeof(ARRAY[0])); } As you can see, the first one has the problem of being a macro (for the moment I consider that a problem) and the other one has the problem of not being able to get the size of an array at compile time; ie I can't write: enum ENUM{N=sizeof_array(ARRAY)}; or BOOST_STATIC_ASSERT(sizeof_array(ARRAY)==10);// Assuming the size 10.. Does anyone know if this can be solved? Update: This question was created before constexpr was introduced. Nowadays you can simply use: template <typename T> constexpr auto sizeof_array(const T& iarray) { return (sizeof(iarray) / sizeof(iarray[0])); }
Try the following from here: template <typename T, size_t N> char ( &_ArraySizeHelper( T (&array)[N] ))[N]; #define mycountof( array ) (sizeof( _ArraySizeHelper( array ) )) int testarray[10]; enum { testsize = mycountof(testarray) }; void test() { printf("The array count is: %d\n", testsize); } It should print out: "The array count is: 10"
In C++1x constexpr will get you that: template <typename T, size_t N> constexpr size_t countof(T(&)[N]) { return N; }
The best I can think of is this: template <class T, std::size_t N> char (&sizeof_array(T (&a)[N]))[N]; // As litb noted in comments, you need this overload to handle array rvalues // correctly (e.g. when array is a member of a struct returned from function), // since they won't bind to non-const reference in the overload above. template <class T, std::size_t N> char (&sizeof_array(const T (&a)[N]))[N]; which has to be used with another sizeof: int main() { int a[10]; int n = sizeof(sizeof_array(a)); std::cout << n << std::endl; } [EDIT] Come to think of it, I believe this is provably impossible to do in a single "function-like call" in C++03, apart from macros, and here's why. On one hand, you will clearly need template parameter deduction to obtain size of array (either directly, or via sizeof as you do). However, template parameter deduction is only applicable to functions, and not to classes; i.e. you can have a template parameter R of type reference-to-array-of-N, where N is another template parameter, but you'll have to provide both R and N at the point of the call; if you want to deduce N from R, only a function call can do that. On the other hand, the only way any expression involving a function call can be constant is when it's inside sizeof. Anything else (e.g. accessing a static or enum member on return value of function) still requires the function call to occur, which obviously means this won't be a constant expression.
It's not exactly what you're looking for, but it's close - a snippet from winnt.h which includes some explanation of what the #$%^ it's doing: // // RtlpNumberOf is a function that takes a reference to an array of N Ts. // // typedef T array_of_T[N]; // typedef array_of_T &reference_to_array_of_T; // // RtlpNumberOf returns a pointer to an array of N chars. // We could return a reference instead of a pointer but older compilers do not accept that. // // typedef char array_of_char[N]; // typedef array_of_char *pointer_to_array_of_char; // // sizeof(array_of_char) == N // sizeof(*pointer_to_array_of_char) == N // // pointer_to_array_of_char RtlpNumberOf(reference_to_array_of_T); // // We never even call RtlpNumberOf, we just take the size of dereferencing its return type. // We do not even implement RtlpNumberOf, we just decare it. // // Attempts to pass pointers instead of arrays to this macro result in compile time errors. // That is the point. // extern "C++" // templates cannot be declared to have 'C' linkage template <typename T, size_t N> char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N]; #define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A))) The RTL_NUMBER_OF_V2() macro ends up being used in the more readable ARRAYSIZE() macro. Matthew Wilson's "Imperfect C++" book also has a discussion of the techniques that are used here.
The Problem I like Adisak's answer: template <typename T, size_t N> char ( &_ArraySizeHelper( T (&arr)[N] ))[N]; #define COUNTOF( arr ) (sizeof( _ArraySizeHelper( arr ) )) It's what Microsoft uses for the _countof macro in VS2008, and it's got some nice features: It operates at compile time It's typesafe (i.e. it will generate a compile-time error if you give it a pointer, which arrays degrade too all too easily) But as pointed out by Georg, this approach uses templates, so it's not guaranteed to work with local types for C++03: void i_am_a_banana() { struct { int i; } arr[10]; std::cout << COUNTOF(arr) << std::endl; // forbidden in C++03 } Fortunately, we're not out luck. The Solution Ivan Johnson came up with a clever approach that wins on all accounts: it's typesafe, compile-time, and works with local types: #define COUNTOF(arr) ( \ 0 * sizeof(reinterpret_cast<const ::Bad_arg_to_COUNTOF*>(arr)) + \ 0 * sizeof(::Bad_arg_to_COUNTOF::check_type((arr), &(arr))) + \ sizeof(arr) / sizeof((arr)[0]) ) struct Bad_arg_to_COUNTOF { class Is_pointer; // incomplete class Is_array {}; template <typename T> static Is_pointer check_type(const T*, const T* const*); static Is_array check_type(const void*, const void*); }; For those who are interested, it works by inserting two "tests" before the standard sizeof-based array-size macro. Those tests don't impact the final calculation, but are designed to generate compile errors for non-array types: The first test fails unless arr is integral, enum, pointer, or array. reinterpret_cast<const T*> should fail for any other types. The second test fails for integral, enum, or pointer types. Integral and enum types will fail because there's no version of check_type that they match, since check_type expects pointers. Pointer types will fail because they'll match the templated version of check_type, but the return type (Is_pointer) for the templated check_type is incomplete, which will produce an error. Array types will pass because taking the address of an array of type T will give you T (*)[], aka a pointer-to-an-array, not a pointer-to-a-pointer. That means that the templated version of check_type won't match. Thanks to SFINAE, the compiler will move on to the non-templated version of check_type, which should accept any pair of pointers. Since the return type for the non-templated version is defined completely, no error will be produced. And since we're not dealing with templates now, local types work fine.
If you are on a Microsoft only platform, you can take advantage of the _countof macro. This is a non-standard extension which will return the count of elements within an array. It's advantage over most countof style macros is that it will cause a compilation error if it's used on a non-array type. The following works just fine (VS 2008 RTM) static int ARRAY[5]; enum ENUM{N=_countof(ARRAY)}; But once again, it's MS specific so this may not work for you.
You can't solve it in general, thats one the reasons for array wrappers like boost array (plus stl-style behaviour of course).
It appears not to be possible to obtain the sizeof array as a compile-time constant without a macro with current C++ standard (you need a function to deduce the array size, but function calls are not allowed where you need a compile-time constant). [Edit: But see Minaev's brilliant solution!] However, your template version isn't typesafe either and suffers from the same problem as the macro: it also accepts pointers and notably arrays decayed to a pointer. When it accepts a pointer, the result of sizeof(T*) / sizeof(T) cannot be meaningful. Better: template <typename T, size_t N> size_t sizeof_array(T (&)[N]){ return N; }
Without C++0x, the closest I can get is: #include <iostream> template <typename T> struct count_of_type { }; template <typename T, unsigned N> struct count_of_type<T[N]> { enum { value = N }; }; template <typename T, unsigned N> unsigned count_of ( const T (&) [N] ) { return N; }; int main () { std::cout << count_of_type<int[20]>::value << std::endl; std::cout << count_of_type<char[42]>::value << std::endl; // std::cout << count_of_type<char*>::value << std::endl; // compile error int foo[1234]; std::cout << count_of(foo) << std::endl; const char* bar = "wibble"; // std::cout << count_of( bar ) << std::endl; // compile error enum E1 { N = count_of_type<int[1234]>::value } ; return 0; } which either gives you a function you can pass the variable to, or a template you can pass the type too. You can't use the function for a compile time constant, but most cases you know the type, even if only as template parameter.
Now STL libraries are available to decide/select array size compile time #include <iostream> #include <array> template<class T> void test(T t) { int a[std::tuple_size<T>::value]; // can be used at compile time std::cout << std::tuple_size<T>::value << '\n'; } int main() { std::array<float, 3> arr; test(arr); } Output: 3
How to precompute array of values?
Is there a way to pre-compute an array of values based on templates? In the following example I would like the 'powers_of_2' array to have 256 values computed at compile-time if that is possible without having to type all of the values. #include <iostream> using namespace std; template <int X, char Y> struct power { enum { value = X * power<X,Y-1>::value }; }; template <int X> struct power<X,1> { enum { value = X }; }; template <int X> struct power<X,0> { enum { value = 1 }; }; int _tmain(int argc, _TCHAR* argv[]) { int powers_of_2[] = { power<2,0>::value, power<2,1>::value, ..., power<2,255>::value }; cout << powers_of_2[1] << endl; return 0; }
Unless you plan on using a big integer package you will overflow the integer type at 2^32 (or 2^64, depending), but to answer your real question look at this wikipedia article on template metaprogramming.
That is exactly what a macro is useful for...
Holding the value 2^255 would require 32 bytes. This cannot be held in an int; you'd need a char array typedef unsigned char BYTE32[32]; BYTE32 powers_of_2[256] = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0}, // : // : {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} };
What I do in situations like that is write a small program that generates and writes to a file the array initialization in C++ source and then #include that file. This technique is simple and effective.
You could easily write a small script to prepopulate the array for you using your preferred scripting language. Depending on the compiler and preprocessor you use, you should also be able to do it as a macro.
I agree with Lokkju. It is not possible to initialize the array by only means of template metaprogramming and macros in this case are very useful. Even Boost libraries make use of macros to implement repetitive statements. Examples of useful macros are available here: http://awgn.antifork.org/codes++/macro_template.h