Is it possible that the below code can be compiled with #CompileStatic?
import groovy.transform.CompileStatic
#CompileStatic
class CompileStaticTest {
List<Number> numbers = []
void addWithCase(something) {
switch (something) {
case Integer: numbers << something; break // compile error
case Float: numbers << something; break // compile error
}
}
void addWithInstanceof(something) {
if (something instanceof Integer) {
numbers << something // compile error
}
if (something instanceof Float) {
numbers << something // compile error
}
}
}
Usage:
test = new CompileStaticTest()
test.addWithCase(11)
test.addWithCase(12f)
test.addWithCase('13')
test.addWithInstanceof(21)
test.addWithInstanceof(22f)
test.addWithInstanceof('23')
println test.numbers
Currently there are compile errors:
[Static type checking] - Cannot call <T> java.util.List <Number>#leftShift(T) with arguments [java.lang.Object]
The type of something is known by switch-case or instanceof so the cast could be done automatically, no? Maybe I am just presenting a too simple example and implementing the requested functionality is not suitable for more complex code.
This sounds like a bug, because the following is allowed:
if (something instanceof Integer) {
something.intValue()
}
Maybe filling a JIRA?
Related
I am using std::list's predicate to update the list based on predicate. But calling in the OnInitDialog() throws compilation error. My code is as follows:
The below is .h:
class CDlgWindow : public CDialog
{
private:
bool single_digit (const int &value);
int _days;
}
The below is .cpp:
CDlgWindow::CDlgWindow(CWnd* pParent, CString strInfo, int days) //ctor
{
_days = days;
//_strInfo = strInfo
}
bool CDlgWindow::single_digit(const int& value)
{
return (value >= _days);
}
BOOL CDlgWindow::OnInitDialog()
{
CDialog::OnInitDialog();
CenterWindow();
.
.
.
int numArr[] = {10,20,30,40};
int size = sizeof(numArr)/sizeof(numArr[0]);
std::list<int> numList (numArr, numArr+size);
numList.remove_if(single_digit); //Error C3867 here!
.
.
}
Complete error message:
Error C3867 function call missing argument list, use '&CDlgWindow::single_digit' to create a pointer to member.
I am trying to understand the functors concept. As I checked in C++11, we have lambdas for easier implementation. Please guide me to understand more on this issue. Thanks!
std::list's remove_if member needs a unary predicate (p) that operates on values (v). The expression p(v) must be valid. Which it isn't if p is a non-static class member (see repro).
There are two options:
Make the predicate (single_digit) a static class member:
class CDlgWindow : public CDialog
{
private:
static bool single_digit (const int &value);
// ...
}
Make the predicate a free function:
bool single_digit(int const& value) {
static int days_ = ...;
return (value >= days_);
}
If you go with option 1 you will have to make _days static as well, since a static member function cannot access non-static instance data. If _days is a compile-time constant, make sure to mark it const as well. That'll open up some compiler optimizations.
This is all hoping that things haven't significantly changed between C++98 and C++11. It's hard to find a C++98 compiler to verify this.
Is there a way to convert a string to an enum in vala:
string foo = "Enum1";
MY_ENUM theEnum = MY_ENUM.get_value_by_name(foo);
enum MY_ENUM {
Enum1,
Enum2,
Enum3
}
So in this example "theEnum" would have the value: MY_ENUM.Enum1
It is possible using the runtime type system provided by GLib's GObject library. There are EnumClass and EnumValue. These provide introspection at runtime and allow an enum to be initialised from a string.
The syntax is a bit complex at present, although it may be possible for someone to modify the Vala compiler to make it easier, but that is a significant piece of work.
An example:
void main () {
try {
MyEnum? the_enum_value;
the_enum_value = MyEnum.parse ("FIRST");
print (#"$(the_enum_value)\n");
} catch (EnumError error) {
print (#"$(error.message)\n");
}
}
errordomain EnumError {
UNKNOWN_VALUE
}
enum MyEnum {
FIRST,
SECOND,
THIRD;
public static MyEnum parse (string value) throws EnumError {
EnumValue? a;
a = ((EnumClass)typeof (MyEnum).class_ref ()).get_value_by_name ("MY_ENUM_" + value);
if (a == null) {
throw new EnumError.UNKNOWN_VALUE (#"String $(value) is not a valid value for $(typeof(MyEnum).name())");
}
return (MyEnum)a.value;
}
}
I want to read a line from input and convert it to generic type.
something like
fun <T> R() : T {
return readLine()!!.toType(T)
}
so for R<int>() it will call toInt() for long toLong() etc.
how to achieve such a thing?
And btw is there a possibility to have a default generic type (C++ has that) in case you want provide one
You can write generic inline function with reified type parameter:
inline fun <reified T> read() : T {
val value: String = readLine()!!
return when (T::class) {
Int::class -> value.toInt() as T
String::class -> value as T
// add other types here if need
else -> throw IllegalStateException("Unknown Generic Type")
}
}
Reified type parameter is used to access a type of passed parameter.
Calling the function:
val resultString = read<String>()
try {
val resultInt = read<Int>()
} catch (e: NumberFormatException) {
// make sure to catch NumberFormatException if value can't be cast
}
Following this tutorial, http://msdn.microsoft.com/en-us/library/vstudio/3bfsbt0t.aspx I implement this code:
class Esame: public CObject
{
public:
INT voto;
INT crediti;
BOOL lode;
CString nome;
Esame(){}
Esame(CString nome, INT voto, BOOL lode, INT crediti) :nome(nome), voto(voto), lode (lode), crediti(crediti) {}
void Serialize(CArchive& ar);
protected:
DECLARE_SERIAL(Esame)
};
IMPLEMENT_SERIAL(Esame, CObject, 1)
void Esame::Serialize(CArchive& ar){
CObject::Serialize(ar);
if (ar.IsStoring())
{
ar << voto << lode << crediti;
}
else
{
ar >> voto >> lode >> crediti;
}
}
then I call:
CFile file(_T("file.and"), CFile::modeCreate);
CArchive afr(&file, CArchive::store);
Esame e;
afr << e;
but i get
<< operator no operator found which takes a left-hand of type cArchive
That's because you didn't provide an overload of operator<< for your class Esame. The article you linked to doesn't do this either, so perhaps you intended to do this instead:
CFile file(_T("file.and"), CFile::modeCreate);
CArchive afr(&file, CArchive::store);
Esame e;
e.Serialize(ar);
So, you call the Serialize function directly, and the implementation in your class uses operator<< to serialize the required primitive member variables and calls Serialize on other complex objects.
As the tutorial shows:
void CCompoundObject::Serialize( CArchive& ar )
{
CObject::Serialize( ar ); // Always call base class Serialize.
m_myob.Serialize( ar ); // Call Serialize on embedded member.
m_pOther->Serialize( ar ); // Call Serialize on objects of known exact type.
// Serialize dynamic members and other raw data
if ( ar.IsStoring() )
{
ar << m_pObDyn;
// Store other members
}
else
{
ar >> m_pObDyn; // Polymorphic reconstruction of persistent object
//load other members
}
}
afr << &e;
pointer type needed.
I'm trying to recompile older code in latest Visual Studio (2008) and code that worked previously now fails to compile. One of the problems is due to overloaded operators for my class. below there is simplified class to demonstrate the problem. If I remove casting operators for int and char* then it works fine. So one of the ways to fix my issue is to replace them with procedures to_char and to_int and use them instead but it will require a lot of changes in the code (that class is heavily used). There must be some better, smarter way to fix it. any help is greatly appreciated :-)
class test
{
public:
test();
test(char* s2);
test(int num);
test(test &source);
~test();
operator char*();
operator int();
};
test::test() {
}
test::test(char* s2) {
}
test::test(int num) {
}
test::test(test &source) {
}
test::operator char*() {
}
test::operator int() {
}
test test_proc() {
test aa;
return aa;
}
int test_proc2(test aa)
{
return 0;
}
int main()
{
test_proc2(test_proc());
}
//test.cpp(60) : error C2664: 'test_proc2' : cannot convert parameter 1 from 'test' to 'test'
// Cannot copy construct class 'test' due to ambiguous copy constructors or no available copy constructor
Try changing
test(test &source);
to
test(const test &source);
The issue is that the test_proc call returns a temporary test object, which can be passed to a function that accepts a const reference, but not a plain reference.