I get a compilation error
[Error 1 (PE114) Type "array[0..1] of ConsoleApplication.MyEnum" used from type "ConsoleApplication." must be public D:\PrismProjects\ConsoleApplication\ConsoleApplication\Program.pas 14 42 ConsoleApplication]
when I try to compile the following code:
namespace ConsoleApplication;
interface
type
ConsoleApp = class
public
class method Main(args: array of string);
end;
MyEnum = (F, T);
const
EnumOfBool: array[boolean] of MyEnum = [MyEnum.F, MyEnum.T];
implementation
class method ConsoleApp.Main(args: array of string);
begin
Console.WriteLine('Hello World.');
end;
end.
Where is MyEnum defined? I'm pretty sure wherever that is, it is not marked as public (as the error message suggests), but it's left on the default visibility (which is private in .NET).
Then RRUZ is correct in his comment, you should avoid global declarations. The Oxygene compiler needs to create a (invisible, auto-generated) class containing this as a static (class) member anyways because .NET does not allow for global declarations, so you should do it 'right' in the first place.
Related
I want to be able to retrieve the names for the types in an enumeration without having to actually assign a variable to them. Hence, given an enumeration like this
class my_class;
typedef enum bit {
ONE,
TWO
} fsm_state_t;
endclass
I know I can access the name of a declared variable like this:
class another_class;
...
my_class::fsm_state_t state = my_class::ONE;
print(state.name());
...
endclass
Is it possible to access the names of the enum without actually having to declare and assign a variable? What I mean is something like this:
class another_class;
...
print(my_class::ONE);
print(my_class::TWO);
...
endclass
No, built-in methods cannot be called on types.
if someday the type is changed, the compiler notifies that the print
must be changed as well.
By simply "using" the enumeration within your code, if it goes away you'll get a compile error. That seems to be what you're duplicating. A more practical duplication would be to value check every enum:
class another_class;
...
if (my_class::ONE!=0) print("ONE has changed!");
if (my_class::TWO!=1) print("TWO has changed!");
...
endclass
EDIT: or create a wrapper class for enums
virtual class enum_wrap#(type T);
static function string name(T obj);
return obj.name();
endfunction
endclass
program testbench;
initial begin
typedef enum {ZERO, ONE, TWO, THREE} numbers_t;
$display("ENUM without variable: %s", enum_wrap#(numbers_t)::name(THREE));
end
endprogram
prints:
ENUM without variable: THREE
Why it is not possible to cast something that extends number to number?
Here is simple example in which I'm trying to pass enum as a generic argument to function.
enum Ev {A, B}
function fun<E extends number>(x: {[ix: number]: any}, e: E)
{
return x[<number>e]
}
// no error here, so I assume is true that `Ev extends number`
fun({0:0}, Ev.A)
It seems a bit inconsistent that some type extends number but I get this error when trying to cast it to number:
Neither type 'E' nor type 'number' is assignable to the other.
Edit: Here is almost the same example but with class instead of number (this compiles without error):
class A {}
function fun<E extends A>(x: {[ix: number]: any}, e: E)
{
return x[<A>e]
}
Primitive types cannot be inherited from, as some have special "abilities" that require a special instance, and creating a new derived object would prevent that ability. For instance, there is no way to call the string constructor for a new custom derived object, so no way to apply it to a user instance. This is why nothing inherits from number, or anything else.
Why it is not possible to cast something that extends number to number?
As Ryan has pointed out in this issue, it seems like a bug in the language; however, take note that this form of constraint is only useful when the return type of the function is the constraint on the type parameter. For example:
function f<T extends number>(input: T) : T { return input; }
var t = f(Ev.A); // t : Ev
An issue with the constraint in the function you provided, is that it doesn't prevent passing in a number value. Since it's not possible to constrain to an enum member, you might as well just define your function with the constraint on the parameter instead:
function fun(x: {[ix: number]: any}, e: number)
{
return x[e];
}
A complaint you had with doing this was that it wasn't self documenting code. I would say it's better to give your function a descriptive name that says its intent rather than relying on generics that offer no constraint benefit beyond a number constraint. Also remember that there's no way to force a developer to write the generic part when calling the function. They can easily write fun({0:0}, Ev.A) instead of fun<Ev>({0:0}, Ev.A).
I write a program with my class:
class COrder
{
public:
COrder();
~COrder();
public:
...
CList < CItem > m_oItem;
...
};
which suppose to have list od object of my other class:
class CItem
{
public:
CItem();
~CItem();
public:
int m_i;
double m_d;
CString m_o;
};
and compiler give me error like this in title. Any ideas why ?
In program I use COrder in map:
CMap <CString, LPCTSTR, COrder, COrder> m_map
Quote:
Add copy-constructor and assignment operator to your class COrder.
I add operator= to my class:
COrder& operator=( const COrder oNewOrder )
{
...
m_oItem.AddTail( oNewOrder.m_oItem.GetTail() );
...
return *this;
}
but what you mean by adding "copy-constructor" ?
http://msdn.microsoft.com/en-us/library/ccb3dh5c.aspx i found this but how to implement it in my code. i can't change CList class.
http://www.codeproject.com/Articles/13458/CMap-How-to
Add copy-constructor and assignment operator to your class COrder. This makes the class copyable.
[If class is used in as Key then you need HashKey() and CompareElemenst() in that class]
Also note that STL containers are superior to MFC containers.
You get an error because CMap has default copy-ctor but CMap and CList is derived from CObject and CObject declares private copy constructor and operator=.
So, CMap doesn't offer a copy semantic "out of the box".
I would suggest you to use STL std::map container, which is designed in a
way to implement copy semantic out-of-the-box.
What you don't have with STL out of the box is serialization only.
Note that std::map does not have the confusing ARG_KEY and ARG_VALUE
templates.
std::map just has the Key and Type template arguments (in its basic form).
http://msdn.microsoft.com/en-us/library/s44w4h2s%28VS.80%29.aspx
Or else you can go by the pointer way as Ajay suggested by which you will just shut up the compiler.
The problem statement:
CList<CItem> m_oItem;
And the trigger statement (or some usage):
CMap <CString, LPCTSTR, COrder, COrder> m_map;
Why? Well, CMap would call copy constructor and/or assignment operator for COrder. You didn't provide any, but compiler provides them from your class (i.e. for COrder). This class contains a CList object, which is inherited from CObject. CObject doesn't provide (or better say: Prevents) copy-constructor or assignment operator.
As a result, the compiler raises the error. Unfortunately, the (bad) compiler doesn't give you back-trace of this error.
Best bets for as the solution:
CList < CItem* > m_oItem;
CList<CItem> *m_poItem;
Use or implement your own collection.
I have taken a look at a C# struct FooStruct in ILDASM, and have seen the following:
ILDASM here displays two differing declarations:
one starting with .class value public (rear window & front window's title bar)
one starting with just .class public (front window)
And I wonder which syntax (if not both) is the correct one for declaring a value type? Is the value modifier strictly necessary, or optional, or a syntax error?
Short answer: Value type definitions only require extends [mscorlib]System.ValueType; the value attribute appears to be optional and has no apparent effect.
I assume that the CLI specification (ECMA-335) would be the best place to look for an authorative answer.
MUST a value type definition include the value attribute?
Section II.10 deals with defining types. More specifically, subsection II.10.1.3 states:
The type semantic attributes specify whether an interface, class, or value type shall be defined. … If [the interface] attribute is not present and the definition extends
(directly or indirectly) System.ValueType, and the definition is not for System.Enum, a value type shall be defined (§II.13). Otherwise, a class shall be defined (§II.11).
The value attribute is not mentioned at all in the whole section.
Conclusion: A correct value type definition does not have to include value. Deriving from System.ValueType is sufficient.
MAY a value type definition include the value modifier?
The CLI standard also contains a grammar for ILASM (in section VI.C.3). According to that grammar, there exists a value attribute for .class type definitions. I additionally searched the standard for concrete value type definitions and found these examples:
.class public sequential ansi serializable sealed beforefieldinit System.Double extends System.ValueType …
.class private sealed Rational extends [mscorlib]System.ValueType …
.class value sealed public MyClass extends [mscorlib]System.ValueType …
Conclusion: A value attribute may be included in a value type definition.
And what does the value attribute MEAN?
I tried to compile these three IL type definitions into an assembly:
.class public sealed … A extends [mscorlib]System.ValueType { … }
.class value public sealed … B extends [mscorlib]System.ValueType { … }
.class value public sealed … C extends [mscorlib]System.Object { … } // !!!
There was no compilation error, even though the value attribute is used in a reference type declaration (see last line). Looking at the resulting assembly using Visual Studio 2012's Object Browser reveals two value types (struct) A and B, and one reference type (class) C.
Speculation: The presence of the value attribute has no effect whatsoever on the type definition. It is only there as a potential aid for humans in spotting value type definitions.
This great book contains simple
answer: when you provide extends clause then value flag is ignored, but if you doesn't provide
extends and use value then ilasm will declare given type as value type.
In other words value was introduced as syntactic sugar, to quickly declare value type.
I'm trying to create an iterator which only can dereference to real value types, not to references.
Is this possible using boost::iterator_facade, or does it require me to have values that can be returned by adress\reference.
To be more specfic, my iterator returns a std::pair of references, which means my iterators value_type is not stored anywhere, but created on the fly on dereferencing (like std::map::iterator).
Yes, thing you want is possible. Please, take a look at boost/iterator_facade.hpp (example is for Boost lib of version 1.49.0 but it is ok for its new distributions also):
template <
class Derived
, class Value
, class CategoryOrTraversal
, class Reference = Value&
, class Difference = std::ptrdiff_t
>
class iterator_facade
Template argument Reference is the key. You should just specify Reference when deriving from boost::iterator_facade. For example, your code can look like as the following:
template<typename value_type>
class custom_iterator
: public boost::iterator_facade<
custom_iterator<value_type>,
value_type,
boost::forward_traversal_tag,
value_type
>
{
...
value_type dereference() const{ return value_type(...); }
...
};