I would like to use Boost Phoenix to generate a lambda function for use in a std::find_if operation on a structure that contains reference-type members. A contrived example is as follows:
struct MyStruct
{
MyStruct() : x(0) {}
int& x;
};
std::vector<MyStruct> AllStructs;
// Search the array for an element for which x == 5
const std::vector<MyStruct>::const_iterator& it =
find_if(
AllStructs.begin(),
AllStructs.end(),
bind(&MyStruct::x, arg1) == 5
);
If MyStruct::x is of type int instead of int&, it compiles fine. But with the reference member I get a "pointer to reference member is illegal" error.
From poking around on the net, it seems like I need to use Phoenix's 'ref' functionality, but I can't seem to figure out the required syntax.
Does anyone know how to get this to work for type 'int&' ?
Sorry that this is far too late, but for future reference, you can use a member pointer:
std::vector<MyStruct>::const_iterator it =
find_if(AllStructs.begin(), AllStructs.end(),
(&boost::phoenix::arg_names::arg1)->*&MyStruct::x == 5
);
You cannot create a pointer to a reference member, just as you cannot create a pointer to a reference. The answer from Daniel James could work only if x was a plain int, rather than int&. See phoenix.modules.operator.member_pointer_operator also.
Related
I searched but not found anything can help me.
I have the following C struct:
struct Home {
int num;
int city_ID;
int area_ID;
};
How do I write this in Lua?
Thanks in advance.
Tables is the closest thing to a struct that you get in Lua:
local s = {}
s.num = 2
s.city_id = 234
s.area_id = 2345
Now you can use struct syntax on it:
print(s.area_id)
Lua provides tables, which can be used as dynamic structs, in which fields are added dynamically.
You could create a table for your example with this code:
s = {
num = 2,
city_id = 234,
area_id = 2345,
}
To access its fields, use s.area_id, etc.
Read Lua 5.3 reference manual.
You'll either use tables or (for struct-s implemented by some C code!) userdata.
I'm porting a C library to Go. A C function (with varargs) is defined like this:
curl_easy_setopt(CURL *curl, CURLoption option, ...);
So I created wrapper C functions:
curl_wrapper_easy_setopt_str(CURL *curl, CURLoption option, char* param);
curl_wrapper_easy_setopt_long(CURL *curl, CURLoption option, long param);
If I define function in Go like this:
func (e *Easy)SetOption(option Option, param string) {
e.code = Code(C.curl_wrapper_easy_setopt_str(e.curl, C.CURLoption(option), C.CString(param)))
}
func (e *Easy)SetOption(option Option, param long) {
e.code = Code(C.curl_wrapper_easy_setopt_long(e.curl, C.CURLoption(option), C.long(param)))
}
The Go compiler complains:
*Easy·SetOption redeclared in this block
So does Go support function (method) overloading, or does this error mean something else?
No it does not.
See the Go Language FAQ, and specifically the section on overloading.
Method dispatch is simplified if it doesn't need to do type matching as well. Experience with other languages told us that having a variety of methods with the same name but different signatures was occasionally useful but that it could also be confusing and fragile in practice. Matching only by name and requiring consistency in the types was a major simplifying decision in Go's type system.
Update: 2016-04-07
While Go still does not have overloaded functions (and probably never will), the most useful feature of overloading, that of calling a function with optional arguments and inferring defaults for those omitted can be simulated using a variadic function, which has since been added. But this comes at the loss of type checking.
For example: http://changelog.ca/log/2015/01/30/golang
According to this, it doesn't: http://golang.org/doc/go_for_cpp_programmers.html
In the Conceptual Differences section, it says:
Go does not support function overloading and does not support user defined operators.
Even though this question is really old, what I still want to say is that there is a way to acheive something close to overloading functions. Although it may not make the code so easy to read.
Say if you want to overload the funtion Test():
func Test(a int) {
println(a);
}
func Test(a int, b string) {
println(a);
println(b);
}
The code above will cause error. However if you redefine the first Test() to Test1() and the second to Test2(), and define a new function Test() using go's ..., you would be able to call the function Test() the way it is overloaded.
code:
package main;
func Test1(a int) {
println(a);
}
func Test2(a int, b string) {
println(a);
println(b);
}
func Test(a int, bs ...string) {
if len(bs) == 0 {
Test1(a);
} else {
Test2(a, bs[0]);
}
}
func main() {
Test(1);
Test(1, "aaa");
}
output:
1
1
aaa
see more at: https://golangbyexample.com/function-method-overloading-golang/ (I'm not the author of this linked article but personally consider it useful)
No, Go doesn't have overloading.
Overloading adds compiler complexity and will likely never be added.
As Lawrence Dol mentioned, you could use a variadic function at the cost of no type checking.
Your best bet is to use generics and type constraints that were added in Go 1.18
To answer VityaSchel's question, in the comments of Lawrence's answer, of how to make a generic sum function, I've written one below.
https://go.dev/play/p/hRhInhsAJFT
package main
import "fmt"
type Number interface {
int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | float32 | float64
}
func Sum[number Number](a number, b number) number {
return a + b
}
func main() {
var a float64 = 5.1
var b float64 = 3.2
println(Sum(a, b))
var a2 int = 5
var b2 int = 3
println(Sum(a2, b2))
}
I'm running into a disconnect between the online documentation and the behavior I see in my programs accessing C structs within GO code. go version says I am using:
go version go1.4.2 linux/amd64
According to the GO CGO documentation:
Within the Go file, C's struct field names that are keywords in Go can be
accessed by prefixing them with an underscore: if x points at a C struct with
a field named "type", x._type accesses the field. C struct fields that cannot
be expressed in Go, such as bit fields or misaligned data, are omitted in the
Go struct, replaced by appropriate padding to reach the next field or the end
of the struct.
I had troubles with this, so made a quick sample program to test it out:
package main
// struct rec
// {
// int i;
// double d;
// char* s;
// };
import "C"
import "fmt"
func main() {
s := "hello world"
r := C.struct_rec{}
r.i = 9
r.d = 9.876
r.s = C.CString(s)
fmt.Printf("\n\tr.i: %d\n\tr.d: %f\n\tr.s: %s\n",
r.i,
r.d,
C.GoString(r.s))
}
When I use underscores as the docs indicate (eg, substitute r._i for r.i above) I get the following compile error:
r._i undefined (type C.struct_rec has no field or method _i)
When I don't use underscores it works fine. I tried this with both pointers and non-pointers. The only other idea I can think of is that maybe it's because I allocated the instances in GO rather than C, is that the case??
Thanks for any help!
The answer is in the very quote you have in your question:
Within the Go file, C's struct field names that are keywords in Go can be accessed by prefixing them with an underscore(…)
i, d, and s are not keywords in Go.
I'm attempting to try and use a string input from a method and set that to a variable of a structure, which i then place in a linked list. I didn't include, all of code but I did post constructor and all that good stuff. Now the code is breaking at the lines
node->title = newTitle;
node->isbn = newISBN;
So newTitle is the string input from the method that I'm trying to set to the title variable of the Book structure of the variable node. Now, I'm assuming this has to do with a issue with pointers and trying to set data to them, but I can't figure out a fix/alternative.
Also, I tried using
strcpy(node->title, newTitle)
But that had an issue with converting the string into a list of chars because strcpy only uses a list of characters. Also tried a few other things, but none seemed to pan out, help with an explanation would be appreciated.
struct Book
{
string title;
string isbn;
struct Book * next;
};
//class LinkedList will contains a linked list of books
class LinkedList
{
private:
Book * head;
public:
LinkedList();
~LinkedList();
bool addElement(string title, string isbn);
bool removeElement(string isbn);
void printList();
};
//Constructor
//It sets head to be NULL to create an empty linked list
LinkedList::LinkedList()
{
head = NULL;
}
//Description: Adds an element to the link in alphabetical order, unless book with
same title then discards
// Returns true if added, false otherwise
bool LinkedList::addElement(string newTitle, string newISBN)
{
struct Book *temp;
struct Book *lastEntry = NULL;
temp = head;
if (temp==NULL) //If the list is empty, sets data to first entry
{
struct Book *node;
node = (Book*) malloc(sizeof(Book));
node->title = newTitle;
node->isbn = newISBN;
head = node;
}
while (temp!=NULL)
{
... //Rest of Code
Note that your Book struct is already a linked list implementation, so you don't need the LinkedList class at all, or alternatively you don't need the 'next' element of the struct.
But there's no reason from the last (long) code snippet you pasted to have an error at the lines you indicated. node->title = newTitle should copy the string in newTitle to the title field of the struct. The string object is fixed size so it's not possible to overwrite any buffer and cause a seg fault.
However, there may be memory corruption from something you do further up the code, which doesn't cause an error until later on. The thing to look for is any arrays, including char[], that you might be overfilling. Another idea is you mention you save method parameters. If you copy, it's ok, but if you do something like
char* f() {
char str[20];
strcpy(str, "hello");
return str;
}
...then you've got a problem. (Because str is allocated on the stack and you return only the pointer to a location that won't be valid after the function returns.) Method parameters are local variables.
The answer you seek can be found here.
In short: the memory malloc returns does not contain a properly constructed object, so you can't use it as such. Try using new / delete instead.
Can any one explain, What is the use of CComPtr over CComQIPtr in COM?
CComPtr<ISampleInterface> Sample1;
CComQIPtr<ISampleInterface> Sample2;
CComQIPtr is for cases when you want to call QueryInterface() in a convenient manner to know whether an interface is supported:
IInterface1* from = ...
CComQIPtr<IInterface2> to( from );
if( to != 0 ) {
//supported - use
}
This way you can request an interface from a pointer to any (unrelated) COM interface and check whether that request succeeded.
CComPtr is used for managing objects that surely support some interface. You use it as a usual smart pointer with reference counting. It is like CComQIPtr, but doesn't allow the usecase described above and this gives you better type safety.
This code:
IUnknown* unknown = ... ;
CComQIPtr<IDispatch> dispatch( unknown );
compiles and maybe yields a null pointer if unknown is bound to an object that doesn't implement IDispatch. You now have to check for that in runtime which is good if you wanted a runtime check in the first place but bad if you'd prefer a compile time type check.
This code:
IUnknown* unknown = ... ;
CComPtr<IDispatch> dispatch( unknown );
will simply not compile - it yields
error C2664: 'ATL::CComPtr::CComPtr(IDispatch *) throw()' : cannot convert parameter 1 from 'IUnknown *' to 'IDispatch *'
which provides for better compile time type safety.
template<class T,
const IID* piid = &__uuidof(T)>
class CComQIPtr: public CComPtr<T>
Former deduces the UUID of given type automatically, via default template argument.
The following MSDN article explains the difference and recommends using CComPtr instead of CComQIPtr
How to: Create and Use CComPtr and CComQIPtr Instances
Remark on the answer of sharptooth. Just tried to compile sth. like
CComQIPtr<IInterface2> to( from );
and failed. Assignment instead worked:
CComQIPtr<IInterface2> to = from;
Unfortunately I have no time to analyse this further...
"ATL uses CComQIPtr and CComPtr to manage COM interface pointers. Both classes perform automatic reference counting through calls to AddRef and Release. Overloaded operators handle pointer operations. CComQIPtr additionally supports automatic querying of interfaces though QueryInterface."
And where do you use one over the other?
When you do not want to call 'QueryInterface()' 'manually', use 'CComQIPtr':
CComQIPtr( T* lp );
CComQIPtr( const CComQIPtr< T, piid >& lp );
If you pass a pointer type derived from T, the constructor sets p to the T* parameter and calls AddRef. If you pass a pointer type not derived from T, the constructor calls QueryInterface to set p to an interface pointer corresponding to piid.