when I tried to create a template class as follows:
template <typename TList>
class Variant
{
public :
std::string toString(); // var.toString()
template<typename T>
std::string toString(); // var.toStrint<int>();
protected:
template <typename T>
std::string toString(T v); // internal Specialization
template <>
std::string toString(int v); // internal Specialization
template <typename T>
const T & get()
{
std::size_t type_index = TypeListNamespace::IndexOf<TList, T>::value ;
if ( type_index == max_num_of_t || type_index != _type_index)
throw std::bad_cast() ;
void * ptr = (void*) &_variant_holder;
T * vptr = reinterpret_cast<T *>(ptr);
return *vptr;
}
};
// CPP FILE:
template <typename TList>
std::string Variant<TList>::toString ()
{
// var.toString()
}
template<typename TList>
template<typename T>
std::string Variant<TList>::toString ()
{
return toString( get<T>() );
}
template<typename TList>
template<typename T>
std::string Variant<TList>::toString (T v)
{
// no default toString method.
return "";
}
template<typename TList>
template<>
std::string Variant<TList>::toString (int v)
{
// Specialized toString for int values:
return Core::Utility::formatString("%i", v );
}
.. other specializations ..
I got the following error:
error C2244: 'Core::Variant<TList>::toString': unable to match function definition to an existing declaration
2> Definition
2> 'std::string Core::Variant<TList>::toString(int)'
2> Available Deklarations
2> 'std::string Core::Variant<TList>::toString(T)'
2> 'std::string Core::Variant<TList>::toString(void)'
2> 'std::string Core::Variant<TList>::toString(void)'
When I had these specializations inside the class definition all compiled right away. So I guess I made something wrong with the template syntax. But its hard to find examples with a mix of class and function templates with specialization. So I ended up here hoping for someone who has a good hint for me.
It seems that you dont have to put "template <>" above your specializations.
If I remove them, everything compiles fine ( look for DON'T TRY THIS AT HOME )
template <typename TList>
class Variant
{
public :
std::string toString(); // var.toString()
template<typename T>
std::string toString(); // var.toStrint<int>();
protected:
template <typename T>
std::string toString(T v); // internal Specialization
// DON'T TRY THIS AT HOME: template <>
std::string toString(int v); // internal Specialization
template <typename T>
const T & get()
{
std::size_t type_index = TypeListNamespace::IndexOf<TList, T>::value ;
if ( type_index == max_num_of_t || type_index != _type_index)
throw std::bad_cast() ;
void * ptr = (void*) &_variant_holder;
T * vptr = reinterpret_cast<T *>(ptr);
return *vptr;
}
};
// CPP FILE:
template <typename TList>
std::string Variant<TList>::toString ()
{
// var.toString()
}
template<typename TList>
template<typename T>
std::string Variant<TList>::toString ()
{
return toString( get<T>() );
}
template<typename TList>
template<typename T>
std::string Variant<TList>::toString (T v)
{
// no default toString method.
return "";
}
template<typename TList>
// DON'T TRY THIS AT HOME: template<>
std::string Variant<TList>::toString (int v)
{
// Specialized toString for int values:
return Core::Utility::formatString("%i", v );
}
.. other specializations ..
As you said, you don't need the template<>, because you didn't specialize the function.
What you did is function overloading!
Related
I assume there is a way to tell WPF how to convert a string target to my source type without having to specify an IValueConverter. WPF will convert string to color, for example. I thought if my type supported an explicit conversion from string to my type, that this would be enough. But this did not work. Is there a way?
Yes, but you have to define a type converter for your type. You can convert from your type to string simply by overriding ToString(). To go the other direction you need a type converter. For example...
public class PartNumberConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if(value is string)
{
return new PartNumber(value as string);
}
return null;
}
}
[TypeConverter(typeof(PartNumberConverter))]
public class PartNumber
{
public PartNumber(string s)
{
string[] e = s.Split('-');
if(e.Length==3)
{
_a = Convert.ToInt32(e[0]);
_b = Convert.ToInt32(e[1]);
_c = Convert.ToInt32(e[2]);
}
}
public PartNumber(int a, int b, int c)
{
_a = a;
_b = b;
_c = c;
}
int _a = 0;
int _b = 0;
int _c = 0;
public override string ToString()
{
return _a + "-" + _b + "-" + _c;
}
}
So not a IValueConverter but still a converter :)
When I try to compile this class, the linker tells me that FooHandler ::getFoo is is not found for architecture x86_64.
enum class Foo {Bar};
class FooHandler {
public:
constexpr std::array<Foo, 1> static getFoo() {
return foo;
}
static constexpr std::array<Foo, 1> foo = { {Foo::Bar} };
};
int main() {
FooHandler::getFoo();
}
Is there anything I am missing here?
Bonus question:
Is there any way I can replace the 1 by a const value?
Problem: I have collection of CircleSegment, when i trying to draw them all at PictureBox, i receive only last CircleSegment from collection on pictureBox. Why?
ref class CircleSegment
{
public:
array<double>^ massive;
Pen^ Blackpen;
int index;
CircleSegment^ SegmentCircleCollection::operator [] ( const int a )
{
return this->Alfa[a];
}
....
}
ref class SegmentCircleCollection
{
public:
Generic::List<CircleSegment^> ^Alfa;
...
}
private: System::Void pictureBox1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e)
{
//Where SegmentCircleCollection^ myCollection;
for each(CircleSegment^ Selected in myCollection->Alfa)
{
e->Graphics->DrawLine(Selected->Blackpen,(int)Selected->massive[6],(int)Selected->massive[7],(int)Selected->massive[8],(int)Selected->massive[9]);
e->Graphics->DrawArc(Selected->Blackpen,(int)Selected->massive[0],(int)Selected->massive[1],(int)Selected->massive[2],(int)Selected->massive[3],(int)Selected->massive[4],(int)Selected->massive[5]);
}
...
}
I have a scenario with three entities:
An interface with one method stub
A class that inherits from `System::Windows::Forms::NativeWindow` and implements the interface
A wrapper class that has a private member of the class type and a public property of the interface type. This class also has a `KeyDown` event member that's to be invoked/raised from the window class
These are the files I'm using:
INativeWindow.h
#pragma once
public interface class INativeWindow
{
void Nothing();
};
CLINativeWindow.h
#pragma once
ref class NWHolder;
public ref class CLINativeWindow : System::Windows::Forms::NativeWindow, INativeWindow
{
public:
NWHolder^ Parent;
virtual void Nothing() sealed;
void DoIt();
};
CLINativeWindow.cpp
#include "stdafx.h"
#include "CLINativeWindow.h"
void CLINativeWindow::Nothing()
{
Console::Write("None");
}
void CLINativeWindow::DoIt()
{
Parent->KeyDown(this, nullptr);
};
NWHolder.h
#pragma once
#include "INativeWindow.h"
#include "CLINativeWindow.h"
public ref class NWHolder
{
internal:
event System::Windows::Forms::KeyEventHandler^ KeyDown;
public:
virtual property INativeWindow^ OwnNativeWindow
{
INativeWindow^ __clrcall get() sealed;
void __clrcall set(INativeWindow^ value) sealed;
}
private:
CLINativeWindow^ nativeWindow_;
};
NWHolder.cpp
#include "stdafx.h"
#include "NWHolder.h"
INativeWindow^ NWHolder::OwnNativeWindow::get()
{
return nativeWindow_;
}
void NWHolder::OwnNativeWindow::set(INativeWindow^ value)
{
nativeWindow_ = dynamic_cast<CLINativeWindow^>(value);
}
At compile time, I get this error:
Error 1 error C3767: 'NWHolder::KeyDown::raise': candidate function(s) not accessible ..\NativeWindows\CLINativeWindow.cpp 10
Is there anything that can be done? I tried even #pragma make_public(System::Windows::Forms::KeyEventHandler) but it failed.
The 'raise' inner method of a C++/CLI event is always declared protected. Add a method on NWHolder named "FireKeyDownEvent", and give it whatever accessibility you like.
I'm trying to access an array of struct inside a struct. This is the relevant C code reduced to the problem:
typedef struct {
int a;
int b;
} fileinfo_t;
typedef struct {
fileinfo_t **file;
int max_files;
} project_t;
In C accessing the array is as easy as this:
int var_a_of_file_0 = project.file[0].a;
int var_b_of_file_1 = project.file[1].b;
How do I implement this in Java? I'm asking this question because I'm new to JNA. So far I read the JNA documentation and tried every example which is somehow related to my problem but with no luck...
I used JNAerator for converting the header file. I don't know for shure if the result is correct:
package test;
import com.ochafik.lang.jnaerator.runtime.LibraryExtractor;
import com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper;
import com.ochafik.lang.jnaerator.runtime.Structure;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.ptr.PointerByReference;
/**
* JNA Wrapper for library <b>test</b><br>
* This file was autogenerated by JNAerator,<br>
* a tool written by Olivier Chafik that uses a few opensource projects..<br>
* For help, please visit NativeLibs4Java , Rococoa, or JNA.
*/
public interface TestLibrary extends Library {
public static final java.lang.String JNA_LIBRARY_NAME = LibraryExtractor.getLibraryPath("test", true, test.TestLibrary.class);
public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(test.TestLibrary.JNA_LIBRARY_NAME, com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper.DEFAULT_OPTIONS);
public static final TestLibrary INSTANCE = (TestLibrary)Native.loadLibrary(test.TestLibrary.JNA_LIBRARY_NAME, test.TestLibrary.class, com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper.DEFAULT_OPTIONS);
public static class fileinfo_t extends Structure<fileinfo_t, fileinfo_t.ByValue, fileinfo_t.ByReference > {
public int a;
public int b;
public fileinfo_t() {
super();
}
public fileinfo_t(int a, int b) {
super();
this.a = a;
this.b = b;
}
protected ByReference newByReference() { return new ByReference(); }
protected ByValue newByValue() { return new ByValue(); }
protected fileinfo_t newInstance() { return new fileinfo_t(); }
public static fileinfo_t[] newArray(int arrayLength) {
return Structure.newArray(fileinfo_t.class, arrayLength);
}
public static class ByReference extends fileinfo_t implements Structure.ByReference {
};
public static class ByValue extends fileinfo_t implements Structure.ByValue {
};
};
public static class project_t extends Structure<project_t, project_t.ByValue, project_t.ByReference > {
/// C type : fileinfo_t**
public PointerByReference file;
public int max_files;
public project_t() {
super();
}
/// #param file C type : fileinfo_t**
public project_t(PointerByReference file, int max_files) {
super();
this.file = file;
this.max_files = max_files;
}
protected ByReference newByReference() { return new ByReference(); }
protected ByValue newByValue() { return new ByValue(); }
protected project_t newInstance() { return new project_t(); }
public static project_t[] newArray(int arrayLength) {
return Structure.newArray(project_t.class, arrayLength);
}
public static class ByReference extends project_t implements Structure.ByReference {
};
public static class ByValue extends project_t implements Structure.ByValue {
};
};
}
Any help would be appreciated.
Since the array of structs does not overlay the containing struct's memory, you need a Pointer or equivalent type for that field. You can then manually derive the structure you need from the base pointer.
I don't think your usage example is valid, however.
Once you index with "[0]", you have a pointer to fileinfo_t, so you would have to use the following (have you actually compiled your example in C?):
int var_a_of_file_0 = project.file[0]->a;
int var_b_of_file_1 = project.file[1]->b;
Ultimately how you extract the actual structures depends on how they are laid out in memory, which is ambiguous in your current explanation.