How to declare a pointer to a template function in D lang? - templates

I'm playing with some D code.
I have some functions filtering on a array:
auto Case1Filters(R)(R lines) if(isInputRange!R) { ... }
auto Case2Filters(R)(R lines) if(isInputRange!R) { ... }
I want to have a function pointer and assign to it one of my filters, so I declared a variable like this:
auto function(R)(R lines) filter = null;
And I get these error when compiling:
conv.d(54): Error: basic type expected, not function
conv.d(54): Error: function declaration without return type. (Note that constructors are always named 'this')
conv.d(54): Error: no identifier for declarator int function(R)(R lines)
conv.d(54): Error: semicolon expected following function declaration
It looks like the compiler thinks that I'm declaring a function.
I tried with an alias, too, but to no avail: is there a way to do this?

You can't have any type of dynamic dispatch to a template, for the same reason you can't have a virtual template function.
Despite all appearances D is a statically typed language which means that all function pointer declarations must have all types available (including the return type auto can only be used when the body is included).
So if R is already declared then you can do:
auto foo(R)(){//R is defined here as some type
Ret function(R lines) filter = null;//no template param when declaring the function pointer and concrete return type
filter = &Case1Filters!R;
filter(r);
}

Related

C++ function pointer to member function inside class

I'd like to store a function pointer to a private member function of my object inside my class.
Basically I want to do this:
MyWindow::MyWindow()
{
std::function<void(int&)> func = this->memberFunction; // ERROR
}
void MyWindow::memberFunction(int& i)
{
// do something
}
When I try to build it the compiler throws an error:
Error C3867: 'MyWindow::memberFunction': non-standard syntax; use '&' to create a pointer to member
The error message for C3867 tells you the first problem: you need to use & to form a function pointer.
Your next problem is that you do not have a function pointer, but a pointer-to-member-function, and that is not compatible with your std::function, which is missing anywhere to store or pass the implicit first argument that holds the "this" pointer.
You can, however, "bind" a value for that argument, in effect hardcoding it into the functor.
You're also going to need to spell it MyWindow::memberFunction rather than this->memberFunction, because that's just the way it is (to quote GCC: "ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function").
So:
using std::placeholders;
std::function<void(int&)> func = std::bind(&MyWindow::memberFunction, this, _1);
Or, using modern techniques:
std::function<void(int&)> func = [this](int& x) { memberFunction(x); };
Or just:
auto func = [this](int& x) { memberFunction(x); };

cannot implicitly convert expression e of type main.T to main.main.T

What does the double main mean? Are there two nested levels of main scope somehow?
Error: cannot implicitly convert expression myFunction(f) of type main.M!(Tuple!(wstring, wstring)*) to main.main.M!(Tuple!(wstring, wstring)*)
The only difference is main.main instead of main.
Error: cannot implicitly convert expression myFunction(f) of type
main.M!(Tuple!(wstring, wstring)*)
to
main.main.M!(Tuple!(wstring, wstring)*)
Context:
M is a struct defined at the top level
the call to myFunction(f) is inside a delegate literal that is immediately called; something like (delegate bool () {myFunction(f);return true;})()
Turns out I had two copies of the struct definition.
M struct definition
definition of myFunction which returns values of type M
M struct definition, again
M = myFunction(f);
thus we have a type mismatch, since the two M's are actually different types, but under the same name

error assigning a function pointer passed as an argument in the constructor to a private instance variable

I'm trying to assign a function pointer that is an argument in the constructor of a class to a private instance variable. (The purpose of this is to be able to pass a callback function to the constructor and use said callback function in member functions of the class.)
I thought I declared the instance variable correctly as a function pointer. The way I read the code snippet, the left operand "cmp" is a pointer, not a function, just like the right operand. (Both are pointers to functions of the same type, or so I thought.) However, the error message says "function as left operand." What am I doing wrong or misinterpreting? Is there a "most vexing parse" issue somewhere?
How can I fix this error and assign the function pointer?
I'm getting the following error message:
"error C2659: '=' : function as left operand"
The error is occurring in the following snippet of code:
template <typename Type>
PQueue<Type>::PQueue(int (cmpFn)(Type,Type))
{
cmp = cmpFn;
}
The compiler is complaining about
cmp = cmpFn;
The constructor prototype is
PQueue(int (cmpFn)(Type, Type) = OperatorCmp);
(OperatorCmp is just another function pointer.)
I declared the instance variable in the private section as
int (cmp)(Type, Type);
The IDE I'm using is Visual C++ 2008 Express, if that matters. (using old version to be compatible with old course materials).
The declaration
int (cmp)(Type, Type);
indeed declares a function, not a function pointer. However, the same syntax used in the parameter list for a function declaration denotes a function pointer, so cmpFn is in fact of type int (*)(Type, Type). Just change the declaration for cmp to
int (*cmp)(Type, Type);
and you'll be good.

Return type object methods

If I have this generic method, where a type Foo object is returned using parameters derived from string s:
Foo createFoo(string s)
{
int index, first, second, third, fourth, fifth;
Foo fooName(int first, int second,int third,int fourth,int fifth);
return fooName;
}
And then in main, I try to do something like this:
Foo newFoo = createFoo(argv[2]);
Why does the compiler give me this error?
file.cc:30:1: error: ‘Foo’ does not name a type file.cc: In function
‘int main(int, char**)’: file.cc:180:38: error: ‘createFoo’ was not
declared in this scope
Coming from Java, doing something like this doesn't usually give me any problems, why would this be a problem in C++? How could I fix this?
Edit 1:
A few suggestions asked where my Foo class definition is located. It was located after the createFoo method so I moved the createFoo method after the Foo class definition segment of code and tried compiling.
Now a new error occurs:
file.cc: In function ‘Foo createFoo(std::string)’: file.cc:153:9:
error: conversion from ‘Foo (*)(int, int, int, int, int)’ to
non-scalar type ‘Foo’ requested
You didn't include the header that defines "Foo", or you forgot to add a using directive to pull it in from the namespace where it is defined.
The statement return fooName; is returning the function fooName, I think you intended to return the result of the function call, it should be something like return fooName(first, second, third, fourth, fifth);
Mert was right in questioning my method location. The method codeblock should have been located after the Foo class definition location within the file.
Concerning your second error, the conversion one:
Foo fooName(int first, int second,int third,int fourth,int fifth);
You intend to create new object instance, passing some parameters to the object constructor. But instead you end up declaring a new function. Remove type names (the "int"s) from parameters to fix this.
You should also be aware of the most vexing parse.

Passing a 2d vector into a function c++

I have a function (assign) in a class (graph) in a header file. The objective of this function is to print a 2d vector:
class Graph
{
public:
void printvec(vector< vector<double> >&PRRMap);
};
I call this function from a cpp file such as:
Graph G;
G.printvec(vector< vector<double> > &PRRmap);
I get the following error:
error: expected primary-expression before ‘&’ token
How can I fix this?
void printvec(vector< vector<double> >&PRRMap);
This is a declaration. It includes formal parameters, each of which specifies a type and an optional name.
G.printvec(a_map);
This is a function call. It includes actual parameters, each of which is an expression, aka value. The type is not named during a function call. But you do need to specify the name of the vector you want printed.
The type of the actual parameter expression is checked against the formal parameter type specified in the function declaration. If they don't match, the compiler will look for a suitable conversion, and if it can't find one, you will get a compile error.
Since your function requires a non-const reference, most conversions will not be allowed here. You should specify the name of a suitable vector-of-vectors object that you have prepared with the data to be printed.
when you call the function you don't need the & operator
only the variable (a valid reference)