c++/cli: sizeof(value struct) as a template argument
-
Friday, January 06, 2012 8:08 PM
EDIT: My problem relates to c++/cli. I didn't make that clear in my original post.
The following code emits a compiler error. cl.exe is version 16.00.40219.01 for 80x86 from VS2010 :
cl.exe /clr main.cpp
main.cpp(21) : error C2975: 'size' : invalid template argument for 'Foo', expected compile-time constant expression main.cpp(4) : see declaration of 'size'
#include <iostream> using namespace std; template <int size> struct Foo { void f() { cout << "size is " << size<< endl; } }; value struct Bar { int x; int y; }; int main() { Foo<sizeof(Bar)> foo; foo.f(); return 0; }
It seems like this is a bug. sizeof(a value struct) is a compile time constant (right?), so it should be fine as a template argument.H^2
All Replies
-
Friday, January 06, 2012 8:28 PM
It could be a bug, yes. I am not an expert at these things. But try it like this:
template<class T, int size = sizeof(T)> struct Foo { void f() { cout << "size is " << size << endl; } };
Jose R. MCP -
Friday, January 06, 2012 8:37 PM
Thanks for the suggestion. That generates the same error, regardless of whether I pass sizeof(Bar) as the second argument, or try to rely on the default template argument.
Foo<Bar> foo1; // Error Foo<Bar, sizeof(Bar)> foo2; // Error Foo<Bar, 8> foo3; // Ok
H^2
-
Friday, January 06, 2012 9:32 PM
Then:
template<class T> struct Foo { void f() { cout << "size is " << sizeof(T) << endl; } };
But in all honesty I don't see how useful that could be alone.
Jose R. MCP -
Friday, January 06, 2012 10:04 PM
Although that works, it doesn't solve the problem that originally got me into this mess.
I am trying to use the inline_array C++/CLI template helper class that is floating around. It's purpose is to embed C style arrays of value types into another managed type (normally a value type structure). inline_array passes sizeof(T) to the constructor of a .net attribute. This works fine when T is a simple type like int, char, float. But it fails when T is a managed struct.
#include <iostream> using namespace std; template <class T, int length> [UnsafeValueType] [StructLayout(LayoutKind::Explicit, Size=(sizeof(T) * length)) ] value struct inline_array { // snip }; value struct Bar { int x; int y; }; int main() { inline_array<int, 3> array1; // OK inline_array<Bar, 3> array2; // Compiler error on sizeof(T) in attribute return 0; }
Since it doesn't like sizeof(T) in the attribute, I figured I could fool it by adding another template parameter and putting the sizeof there.
template <class T, int length, int typeSize=sizeof(T) > [StructLayout(LayoutKind::Explicit, Size=(typeSize* length)) ] value struct inline_array ...
This doesn't compile, even when the attribute is removed. Nor did other similar types of workarounds. So here I am.
So your last code example works, but doesn't really help me in this case. It is interesting that sizeof(T) can appear in the body of the class, but not in an attribute of the class when T is a value struct.
H^2
-
Tuesday, January 10, 2012 9:02 PM
Compiled your code on VS2010 by creating a win32 console application and it works fine for me.Apart from your value struct bar
// TestApp.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> using namespace std; template <int size> struct Foo { void f() { cout << "size is " << size<< endl; } }; struct Bar { int x; int y; }; int _tmain(int argc, _TCHAR* argv[]) { Foo<sizeof(Bar)> foo; foo.f(); return 0; }Thanks
Rupesh Shukla -
Thursday, January 12, 2012 3:13 PM
Yes, it works for native (non-cli) struct. My bug report was specifically for a managed struct (value struct). I should have been more clear.
Try compiling the original code with cl.exe /clr to see the problem.

