Not sure why, but the code in xcode just started working. I am very happy.
Thank you all for your time.
//here is JUCE's code
//==============================================================================
/** This template-overloaded class can be used to convert between var and custom types.
#tags{Core}
*/
template <class Type> struct VariantConverter
{
static Type fromVar (const var& v) { return static_cast<Type> (v); }
static var toVar (const Type& t) { return t; }
};
//here is my addition
template <> struct VariantConverter<Point<int>>
{
static Point<int> fromVar (const var& v)
{
return Point<int>
(
{ v[0].operator int(), v[1].operator int() }
);
}
static var toVar (const Point<int>& p)
{
return Array<var>({ p.getX(), p.getY() });
}
};
Hi, I am not sure how I can achieve the above code. A class like typedef to replace the
Point<int>
would be great. I am appending a JUCE file.
Xcode gives me two errors
/Tools/JUCE/modules/juce_core/containers/juce_Variant.h:41:18: Expected unqualified-id
and
/Tools/JUCE/modules/juce_core/containers/juce_Variant.h:343:46: Expected '>'
Thank you
As there are only static methods you don't need an Object of that type. You should be able to call it like:
typedef Point<int> MyPoint;
MyPoint point(1,2); // call constructor of a Point<int>
var x = VariantConverter::toVar(point); //call static methods of struct
MyPoint point2 = VariantConverter::fromVar(x);
template <>
struct VariantConverter<Point<int>>
{ /* ... */ };
What you have here is a template specialisation. If you want to specialise, you first need a base template before you can compile.
template <typename>
struct VariantConverter;
Sometimes it is useful if only the specialisations exist, then you would just declare the base as above, fare mor common, though, is having a default implementation:
template <typename T>
struct VariantConverter
{
static T fromVar(var const& v);
};
Solely, what shall var be in above example? T as well? Another template parameter of VariantConverter struct? Third option is the one I show: function template parameter:
template <typename T>
struct VariantConverter
{
template <typename var>
static T fromVar(var const& v);
};
You now can provide a default implementation suitable for the majority of types – if there is a reasonable one (otherwise, it might be more appropriate not to implement the default and just have the specialisations).
OK, now we can specialise:
template <>
struct VariantConverter<Point<int>>
// Point<int> now is what previously was T; could be any arbitrary type, not
// necessarily Point<int>, but std::string, double, ...
{
// still, you need to tell what var actually is
// maybe you have defined a class for already? similar to std::vector?
// assuming so this time...
static Point<int> fromVar (var const& v)
{
return Point<int>
(
// are you sure point accepts an initializer list?
// or do you intend to create first a point and then
// use move/copy constructor???
//{ v[0].operator int(), v[1].operator int() }
// rather normal constructor directly:
//v[0].operator int(), v[1].operator int()
// however, explicitly calling cast operators is ugly, rather just cast:
static_cast<int>(v[0]), static_cast<int>(<v[1])
// or C style casts, if you prefer
//(int)v[0], (int)v[1]
// I personally would rather go with the former, though, for being
// more "C++-ish"
);
}
};
Now maybe you are looking for something totally different:
template <typename T>
struct VariantConverter
{
static Point<T> fromVar(std::vector<T> const& v)
{
return Point<T>(v[0], v[1]);
}
};
Finally, as you explicitly asked for:
template <>
struct VariantConverter<Point<int>>
{
using Type = Point<int>;
static Type fromVar(/* ... */);
};
or, for second variant:
template <typename T>
struct VariantConverter
{
using Type = Point<T>;
static Type fromVar( /* ... */);
};
Sorry for my poor communication. English is my first language and despite being educated, I am not gifted at written communication. Here is the bigger context. I am trying to add to an existing class.
//This is the end of their code
//==============================================================================
/** This template-overloaded class can be used to convert between var and custom types.
#tags{Core}
*/
template <class Type> struct VariantConverter
{
static Type fromVar (const var& v) { return static_cast<Type> (v); }
static var toVar (const Type& t) { return t; }
};
//here is my code
template <> struct VariantConverter<Point<int>>
{
static Point<int> fromVar (const var& v)
{
return Point<int>
(
{ v[0].operator int(), v[1].operator int() }
);
}
static var toVar (const Point<int>& p)
{
return Array<var>({ p.getX(), p.getY() });
}
};
Related
I have the following problem: I have a class hierarchy with a base class and two sub-classes. I have implemented a resolve_type function that accepts an instance of the base class and a generic lambda (or similar). The function resolves its type and passes it to the lambda. Inside this lambda, I’d like to check the column’s type within a constexpr-if condition in order to exclude certain types. I have tried to do this with constexpr member functions in the sub-classes, which unfortunately didn’t work.
Code:
class AbstractColumn
{
};
template <typename Type>
class DataColumn : public AbstractColumn
{
public:
constexpr bool is_reference_column() { return false; }
void foo() {}
};
class ReferenceColumn : public AbstractColumn
{
public:
constexpr bool is_reference_column() { return true; }
};
template <typename Functor>
resolve_type(const AbstractColumn & col, const Functor & func);
Usage:
AbstractColumn & col = ...;
...
resolve_type(col, [] (const auto & col)
{
// col could be ReferenceColumn, DataColumn<int>, DataColumn<float>, DataColumn<double>, DataColumn<std::string> ...
if constexpr (!col.is_reference_column()) {
col.foo();
}
});
Compiler Error:
Apple LLVM version 8.1.0 (clang-802.0.42)
error: constexpr if condition is not a constant expression
if constexpr (col.is_reference_column()) {
I know that I could use decltype to get the type and then continue using some template magic, but I had hoped to find something that is a bit more readable. My project already uses boost and its hana library, so solutions could also use these two. Does anyone have any ideas?
Use a static constexpr method instead.
It follows a minimal, working example:
#include<type_traits>
struct A {
static constexpr bool is_reference_column() { return false; }
};
int main() {
[](const auto &col) {
if constexpr(std::decay_t<decltype(col)>::is_reference_column()) {
// ...
}
}(A{});
}
Or just inherits from std::true_type/std::false_type:
#include<type_traits>
struct A: std::true_type {};
int main() {
[](const auto &col) {
if constexpr(std::decay_t<decltype(col)>::value) {
// ...
}
}(A{});
}
Or use an intermediate class template instead of redefining continuously is_reference_column:
#include<type_traits>
template<bool refcol>
struct I {
static constexpr bool is_reference_column = refcol;
};
struct A: I<true> {};
int main() {
[](const auto &col) {
if constexpr(std::decay_t<decltype(col)>::is_reference_column) {
// ...
}
}(A{});
}
Plenty of alternatives, but you cannot simply use col in a constant expression just because you declared it as a const reference. col is a runtime instance of a type T, there is no chance you can use it at compile-time as you tried to do.
I think you're overthinking this. You don't need a member function to just identify the type of the object. You can just look at the type. So at a first go, that's simply:
resolve_type(col, [] (const auto& col)
{
if constexpr (hana::typeid_(col) == hana::type_c<ReferenceColumn>) {
col.foo();
}
});
Even simpler would just be to create an overload set and just use overload resolution. There are several implementations of such a mechanism floating around here, it's especially straightforward to write in C++17. Using that:
resolve_type(col, overload(
[](ReferenceColumn const& ref){
ref.foo();
},
[](auto const& other) {
}));
Assume we have a data structure Foo that maintains a set of elements. It should be possible to associate attributes with the elements as needed. The attributes should be stored in a separate vector each. We implement this by means of variadic templates:
#include <vector>
template <typename ...Attrs>
struct Foo : public Attrs... {
Foo(int n = 0) {
using PackExpansionT = int[];
PackExpansionT{0, (Attrs::values.resize(n), 0)...};
}
};
struct AttrA { std::vector<int> values; };
struct AttrB { std::vector<float> values; };
struct AttrC { std::vector<double> values; };
int main() {
Foo<AttrA, AttrB> foo; // Maintains set of elements with two attributes each.
};
Now, I want a conversion operator with the following semantics:
Foo<AttrB, AttrC> bar = foo; // bar.AttrB::values should be a copy of foo.AttrB::values.
This is only an example. In general, the conversion operator should be able to convert a Foo with arbitrary attributes into another Foo with arbitrary attributes. Attributes associated with both Foos should be copied. Attributes not associated with both can be left defaulted. However, I have no idea how to implement it.
template <typename ...OthersAttrs>
operator Foo<OthersAttrs...>() const {
// ...?
}
We can just make a bunch of independent decisions. First, let's add a constructor so that we can construct Foo from its attribute constituents:
Foo(Attrs const&... attrs)
: Attrs(attrs)...
{ }
Next, for each attribute in Others, we will either downcast this to the appropriate type if possible or return a default-constructed one otherwise:
template <typename... Others>
operator Foo<Others...>() const {
return {get_attr<Others>(this)...};
}
where:
template <class T>
T const& get_attr(T const* v) const {
return *v;
}
template <class T>
T get_attr(...) const {
return T{};
}
An outline I can think of:
template <typename ...OthersAttrs>
operator Foo<OthersAttrs...>() const
{
Foo<OthersAttrs...> rv(GetNSomehow());
(int[]){(CopyAttr<Attrs>(&rv), 0)...};
return rv;
}
template<typename Attr>
void CopyAttr(Attr *rv) const // Overload A
{
rv->values = ((const Attr*)this)->values;
}
template<typename Attr>
void CopyAttr(...) const // Overload B
{
}
The trick here is to go attribute by attribute.
If rv has the attribute the first overload will be chosen and it will be copied.
Otherwise the second overload would be chosen that will do nothing.
If I understand correctly, the object ’A’ defined thus:
typedef struct {
int n;
float *p;
} myStruct;
myStruct A;
is an aggregate with exactly the same layout in memory as the object ‘B’ defined as:
template <typename T> class myTemplateClass
{
public:
int n;
T* p;
};
myTemplateClass<float> B;
So, is there a more elegant way of assigning
A = B;
than having to write
A = *(reinterpret_cast< myStruct *>(&B));
every time?
My reason for asking is that I have to call a library function which exposes an interface with arguments of the form ‘myStruct’, from code where holding my data in the form of myTemplateClass is a great deal more natural.
This requires a bit of boilerplate. Two functions per myStruct, and two functions per template.
In the namespace of myStruct inject these two functions:
auto members( myStruct& s ) {
return std::tie(s.n, s.p);
}
auto members( myStruct const& s ) {
return std::tie(s.n, s.p);
}
in C++11 you have to add a decltype clause to give the return value explicitly. Basically tie the members in the exact order declared.
In the body of the myTemplateClass, declare a friend function members that does something similar:
template <typename T>
class myTemplateClass {
public:
int n;
T* p;
friend auto members( myTemplateClass<T>& self ) {
return std::tie( self.n, self.p );
}
friend auto members( myTemplateClass<T> const& self ) {
return std::tie( self.n, self.p );
}
};
finally, write assign:
template<class Lhs, class Rhs>
void assign_by_members( Lhs& lhs, Rhs const& rhs ) {
members(lhs) = members(rhs);
}
and we are done.
Anyone that declares a free function members that returns something assignable to the other members works. tie does element-wise assign on references, so all is good.
Note that only the one being assigned from needs the const& overload of members and only the one being assigned to needs the & overload of members. So if assignment always goes from template class to C-struct, you can halve that boilerplate.
If you don't like the assign_by_members syntax, you can override operator O as follows:
template <typename T>
class myTemplateClass {
public:
// ... see above for code that goes here
template<class O,class=decltype(members(std::declval<O>())>
operator O() const {
O retval;
assign_by_members( retval, *this );
return retval;
}
};
which also does a test to determine if the type converted to supports members. You could go a step further and test if the members return value can be assigned to from the return value of members(*this), but that adds more boilerplate.
You could make myTemplateClass<T> derive from the correct myStruct depending on the type parameter. You can use template specialization for this:
template <typename T> class myTemplateClass;
// Specialization for float
template <> class myTemplateClass<float> : public myStruct {};
// Specialization for int
template <> class myTemplateClass<int> : public myOtherStruct {};
// And so on for other types...
This way, you can assign instances of myTemplateClass<float> to myStruct, and myTemplateClass<int> to myOtherStruct. (Bonus: You don't have to rely on the "same memory layout" guess.)
If you derive from mystruct, then, u can use a static_cast on it.
As suggested above, template specialization would work too.
I would take static_cast over reinterpret_cast any day.
Below is the working code.
typedef struct {
int n;
float *p;
} myStruct;
myStruct A;
template <typename T> class myTemplateClass:public myStruct
{
public:
int n;
T* p;
};
//myTemplateClass<float> B;
typedef myTemplateClass<float> temp;
temp B;
int main()
{
A = *(static_cast< myStruct *>(&B));
I am trying to write a template class named Binder that bind functions and parameters as whole, distinguished by the returning type of the binded function, this is my approach:
template <typename return_type>
class Binder
{
public:
virtual return_type call() {}
};
invoking call will invoke some pre-binded functions with parameters, and return the result.
I want some template classes inherited from Binder that do the real binding job.
below is a one-parameter-function binding class:
template<typename func_t, typename param0_t>
class Binder_1 : public Binder< ***return_type*** >
// HOW TO DETERMINE THE RETURN TYPE OF func_t?
// decltype(func(param0)) is available when writing call(),
// but at this point, I can't use the variables...
{
public:
const func_t &func;
const param0_t ¶m0;
Binder_1 (const func_t &func, const param0_t ¶m0)
: func(func), param0(param0) {}
decltype(func(param0)) call()
{
return func(param0);
}
}
// Binder_2, Binder_3, ....
This is what I want to achieve:
template<typename func_t, typename param0_t>
Binder_1<func_t, param0_t> bind(const func_t &func, const param0_t ¶m0)
{
reurn Binder_1<func_t, param0_t>(func, param0);
}
// ... `bind` for 2, 3, 4, .... number of paramters
int func(int t) { return t; }
double foo2(double a, double b) { return a > b ? a : b; }
double foo1(double a) { return a; }
int main()
{
Binder<int> int_binder = bind(func, 1);
int result = int_binder.call(); // this actually calls func(1);
Binder<double> double_binder = bind(foo2, 1.0, 2.0);
double tmp = double_binder.call(); // calls foo2(1.0, 2.0);
double_binder = bind(foo1, 1.0);
tmp = double_binder.call(); // calls foo1(1.0)
}
can bind function in boost library be adapted to achieve this functionality?
similar solutions are welcome too!
Introducing std::declval<T>().
This is a dummy function declared as:
template <typename T>
typename std::add_rvalue_reference<T>::type declval();
// This means it returns T&& if T is no a reference
// or T& if T is already a reference
and never actually defined.
It is therefore only to be used within unevaluated contexts such as sizeof or... decltype!
With this, you get:
template<typename func_t, typename param0_t>
class Binder_1: public Binder<decltype(std::declval<func_t>()(std::declval<param0_t>())>
It is a bit verbose, but hey! It works :)
You might be able to use result_of.
Please, consider the code below:
template<typename T>
bool function1(T some_var) { return true; }
template <typename T>
bool (*function2())(T) {
return function1<T>;
}
void function3( bool(*input_function)(char) ) {}
If I call
function3(function2<char>());
it is ok. But if I call
function3(function2());
compiler gives the error that it is not able to deduction the argument for template.
Could you, please, advise (give an idea) how to rewrite function1 and/or function2 (may be, fundamentally to rewrite using classes) to make it ok?
* Added *
I am trying to do something simple like lambda expressions in Boost.LambdaLib (may be, I am on a wrong way):
sort(some_vector.begin(), some_vector.end(), _1 < _2)
I did this:
template<typename T>
bool my_func_greater (const T& a, const T& b) {
return a > b;
}
template<typename T>
bool my_func_lesser (const T& a, const T& b) {
return b > a;
}
class my_comparing {
public:
int value;
my_comparing(int value) : value(value) {}
template <typename T>
bool (*operator<(const my_comparing& another) const)(const T&, const T&) {
if (this->value == 1 && another.value == 2) {
return my_func_greater<T>;
} else {
return my_func_greater<T>;
}
}
};
const my_comparing& m_1 = my_comparing(1);
const my_comparing& m_2 = my_comparing(2);
It works:
sort(a, a + 5, m_1.operator< <int>(m_2));
But I want that it doesn't require template argument as in LambdaLib.
Deduction from return type is not possible. So function2 can't be deduced from what return type you expect.
It is however possible to deduce cast operator. So you can replace function2 with a helper structure like: Unfortunately there is no standard syntax for declaring cast operator to function pointer without typedef and type deduction won't work through typedef. Following definition works in some compilers (works in G++ 4.5, does not work in VC++ 9):
struct function2 {
template <typename T>
(*operator bool())(T) {
return function1<T>;
}
};
(see also C++ Conversion operator for converting to function pointer).
The call should than still look the same.
Note: C++11 introduces alternative typedef syntax which can be templated. It would be like:
struct function2 {
template <typename T>
using ftype = bool(*)(T);
template <typename T>
operator ftype<T>() {
return function1<T>;
}
};
but I have neither G++ 4.7 nor VC++ 10 at hand, so I can't test whether it actually works.
Ad Added:
The trick in Boost.Lambda is that it does not return functions, but functors. And functors can be class templates. So you'd have:
template<typename T>
bool function1(T some_var) { return true; }
class function2 {
template <typename T>
bool operator()(T t) {
function1<T>;
}
};
template <typename F>
void function3( F input_function ) { ... input_function(something) ... }
Now you can write:
function3(function2);
and it's going to resolve the template inside function3. All STL takes functors as templates, so that's going to work with all STL.
However if don't want to have function3 as a template, there is still a way. Unlike function pointer, the std::function (C++11 only, use boost::function for older compilers) template can be constructed from any functor (which includes plain function pointers). So given the above, you can write:
void function3(std::function<bool ()(char)> input_function) { ... input_function(something) ... }
and now you can still call:
function3(function2());
The point is that std::function has a template constructor that internally generates a template wrapper and stores a pointer to it's method, which is than callable without further templates.
Compiler don't use context of expression to deduce its template parameters. For compiler, function3(function2()); looks as
auto tmp = function2();
function3(tmp);
And it don't know what function2 template parameter is.
After your edit, I think what you want to do can be done simpler. See the following type:
struct Cmp {
bool const reverse;
Cmp(bool reverse) : reverse(reverse) {}
template <typename T> bool operator()(T a, T b) {
return reverse != (a < b);
}
};
Now, in your operator< you return an untyped Cmp instance depending on the order of your arguments, i.e. m_2 < m_1 would return Cmp(true) and m_1 < m_2 would return Cmp(false).
Since there is a templated operator() in place, the compiler will deduce the right function inside sort, not at your call to sort.
I am not sure if this help you and I am not an expert on this. I have been watching this post since yesterday and I want to participate in this.
The template cannot deduce it's type because the compiler does not know what type you are expecting to return. Following is a simple example which is similar to your function2().
template<typename T>
T foo() {
T t;
return t;
};
call this function
foo(); // no type specified. T cannot be deduced.
Is it possible to move the template declaration to the class level as follows:
template<typename T>
bool my_func_greater (const T& a, const T& b) {
return a > b;
}
template<typename T>
bool my_func_lesser (const T& a, const T& b) {
return b > a;
}
template <typename T>
class my_comparing {
public:
int value;
my_comparing(int value) : value(value) {}
bool (*operator<(const my_comparing& another) const)(const T&, const T&) {
if (this->value == 1 && another.value == 2) {
return my_func_greater<T>;
} else {
return my_func_greater<T>;
}
}
};
and declare m_1 and m_2 as below:
const my_comparing<int>& m_1 = my_comparing<int>(1);
const my_comparing<int>& m_2 = my_comparing<int>(2);
Now you can compare as follows:
if( m_1 < m_2 )
cout << "m_1 is less than m_2" << endl;
else
cout << "m_1 is greater than m_2" << endl;
I know this is simple and everyone knows this. As nobody posted this, I want to give a try.