Attempt at STL Container - stl

I am attempting to make a version of std::set using a linked list. I think I have implemented it mostly correctly but I am getting a compile error that I cannot decipher. I would appreciate anyone spotting the error in my code, and or explaining how I would go about tracking down an error like this. Meaning an error that goes far into stl functions.
#include <iterator>
#include <cstddef>
template <typename Type>
struct ListNode{
Type info;
ListNode<Type> * next;
ListNode(Type newInfo, ListNode<Type> * newNext) : info(newInfo), next(newNext){
}
ListNode(ListNode<Type>& L): info(L.info), next(L.next){
}
ListNode<Type>& operator=(ListNode<Type>& L){
info = L->info;
next = L->next;
return this;
}
};
template <typename Type>
class SetList{
ListNode<Type> * head;
ListNode<Type> * tail;
public:
typedef ListNode<Type> value_type;
SetList() : head(nullptr), tail(nullptr){
}
SetList(SetList & s){
}
~SetList(){
//ListNode<Type> * cur = head;
//ListNode<Type> * next = cur;
//while(cur){
// next = cur->next;
// delete cur;
// cur = next;
// }
}
struct iterator{
//traits
typedef std::forward_iterator_tag iterator_category;
typedef iterator self_type;
typedef Type value_type;
typedef Type& reference;
typedef Type* pointer;
typedef ptrdiff_t difference_type;
private:
//rename to ihead
ListNode<Type>* ibuf;
public:
iterator(ListNode<value_type>* node) : ibuf(node){}
self_type& operator++(){ibuf = ibuf->next; return *this;}
self_type operator++(int postfix){
self_type cpy = *this;
ibuf = ibuf->next;
return cpy;
}
reference operator*(){return ibuf->info;}
pointer operator->(){return &ibuf->info;}
self_type operator=(const iterator& it){insert(*it);}
bool operator==(const self_type& rhs) const {return ibuf->info == rhs.ibuf->info;}
bool operator !=(const self_type& rhs) const {return ibuf->info != rhs.ibuf->info;}
};
iterator begin(){ return iterator(head);}
iterator end() { return iterator(nullptr);}
// const_iterator begin() { return const_iterator(head);}
// const_iterator end() { return const_iterator(tail);}
Type operator[](int index){
iterator cur(head);
for(int i = 0; i < index; ++i,++cur){
}
return *cur;
}
SetList<Type>& operator=(const SetList<Type>& s){
head = s.head;
tail = s.tail;
return this;
}
iterator find(Type toFind){
ListNode<Type> * cur = head;
while(cur){
if(cur->info == toFind)
return iterator(cur);
}
return this->end();
}
void insert(Type toInsert){
ListNode<Type>* cur = nullptr;
if(head){
cur = new ListNode<Type>(toInsert, head);
head = cur;
}else{
cur = new ListNode<Type>(toInsert, nullptr);
head = cur;
}
}
};
I am calling elsewhere copy on my set, my copy call works with std::set but not my set.
The error I am getting is as follows.
Hope this isn't too much to ask. You don't even have to read my code, even just input on how to track down large errors like this would be much appreciated.

SetList<Type> should have Type as its value_type, not ListNode<Type>.

Related

boost shared_memory_object use of deleted function

use of deleted function in class operator=
old version worked with old compiler but not with new versions
I need this "operator=" overloading for container operation.
#include <boost/interprocess/ipc/message_queue.hpp>
#include <iostream>
using namespace boost::interprocess;
class X {
public:
size_t m_len;
shared_memory_object m_shm;
const char* m_ptr;
X():
m_len(0),
m_shm(shared_memory_object()),
m_ptr(nullptr){}
X(size_t t, const char* n):
m_len(t),
m_shm(shared_memory_object()),
m_ptr(nullptr){
shared_memory_object::remove(n);
m_shm = shared_memory_object(open_or_create,n, read_write);
m_shm.truncate (m_len);
mapped_region region(m_shm, read_write);
m_ptr = static_cast<char*>(region.get_address());
}
X(const X&& x){
m_len = x.m_len;
m_shm = x.m_shm; //error use deleted function
m_ptr = x.m_ptr;
}
virtual ~X(){}
X& operator = (const X&& a) {
if(&a == this) return *this;
m_len = a.m_len;
m_ptr = a.m_ptr;
m_shm = a.m_shm; //error use deleted function
return (*this);
}
const char* get_name(){
return m_shm.get_name();
}
};
int main ()
{
X a = X(22, "test");
X b = a; //Error
return 0;
};
The above class will be used in std::vector and operator= is needed.
boost shared_memory_object has member:
shared_memory_object(shared_memory_object &&);
shared_memory_object& operator=(shared_memory_object &&);
Move operations can only work on non-const objects. Why? Because it steals resources from the source instance, then it must be non-const to be modifiable. So your move operations should take non-const objects:
now should be
----------------------------------------------------------
X(const X&& x) ==> X(X&& x)
X& operator = (const X&& a) { ==> X& operator = (X&& a) {
Named variable is treated as L-value, it implies copy operations are called. You need to use std::move to cast source to R-value reference, then move operations can be called:
m_shm = std::move(x.m_shm); // in move ctor
m_shm = std::move(a.m_shm); // in move assignment operator
and finally to call move ctor:
X b = std::move(a);

Refering within the class to constructor with the this pointer

#include "stdafx.h"
ref class station{
public:
station(){
};
void wrapper_1()
{
this->somefunct(); /*happy*/
};
void wrapper_2()
{
this->station(); /*not happy*/
};
void somefunct(){
System::Console::WriteLine(L"abcde");
};
};
int main(array<System::String^>^ args)
{
station^ temp_1 = gcnew station();
temp_1->wrapper_1();
System::Console::ReadLine();
};
I want to use the this pointer to call my constructor within my station class, it doesn't like this and throws the following error:
error C2273: 'function-style cast' : illegal as right side of '->'
operator.
Can someone explain to me how the constructor differs to other functions when using the pointer this to point to the function. I don't want to take the easy way out using station::station();
example of what I meant to #hans-passant
#include "stdafx.h"
ref class station{
public:
station(int par_1,int par_2)
{
int sum = par_1 + par_2;
System::Console::WriteLine(System::Convert::ToString(sum));
//default value output 13
};
station(){
int pass_1 = 5;
int pass_2 = 8;
station(pass_1,pass_2); /* But why couldn't I use this->station(pass_1,pass_2);*/
};
};
int main(array<System::String^>^ args)
{
station^ obj = gcnew station();
System::Console::ReadLine();
};

updating old NPAPI plugin for Maya 2014

I need some advice on how to update an external web browser plugin for Maya 2014 on windows 7. The plugin was last updated in 2008 and works perfectly in an older browser like Firefox 3. However, any later browser (Firefox 3.5 to 26) immediately breaks the plugin.
The error I am getting in firebug is:
Error: Error calling method on NPObject! return MWTObject.execute(CommandText)
I am a complete novice at API programming and am in way over my head on this one. I think the error is being caused by NPP_GetValue getting called 2 times and the plugin not being able to hanlde it. The main.cpp is as follows:
//-
// ==========================================================================
// Copyright 1995,2006,2008 Autodesk, Inc. All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk
// license agreement provided at the time of installation or download,
// or which otherwise accompanies this software in either electronic
// or hard copy form.
// ==========================================================================
//+
#include "mcp.h"
#include "PluginObject.h"
NPNetscapeFuncs *browser;
NPNetscapeFuncs NPNFuncs;
NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved);
NPError NPP_Destroy(NPP instance, NPSavedData** save);
NPError NPP_SetWindow(NPP instance, NPWindow* window);
NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype);
NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason);
int32 NPP_WriteReady(NPP instance, NPStream* stream);
int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer);
void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname);
void NPP_Print(NPP instance, NPPrint* platformPrint);
int16 NPP_HandleEvent(NPP instance, void* event);
void NPP_URLNotify(NPP instance, const char* URL, NPReason reason, void* notifyData);
NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value);
NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value);
char *NPP_GetMIMEDescription(void) {
return "application/x-mcp::MCP Plugin";
}
NPError OSCALL NP_Initialize(NPNetscapeFuncs* pFuncs)
{
if(pFuncs == NULL)
return NPERR_INVALID_FUNCTABLE_ERROR;
if(HIBYTE(pFuncs->version) > NP_VERSION_MAJOR)
return NPERR_INCOMPATIBLE_VERSION_ERROR;
if(pFuncs->size < sizeof(NPNetscapeFuncs))
return NPERR_INVALID_FUNCTABLE_ERROR;
NPNFuncs.size = pFuncs->size;
NPNFuncs.version = pFuncs->version;
NPNFuncs.geturlnotify = pFuncs->geturlnotify;
NPNFuncs.geturl = pFuncs->geturl;
NPNFuncs.posturlnotify = pFuncs->posturlnotify;
NPNFuncs.posturl = pFuncs->posturl;
NPNFuncs.requestread = pFuncs->requestread;
NPNFuncs.newstream = pFuncs->newstream;
NPNFuncs.write = pFuncs->write;
NPNFuncs.destroystream = pFuncs->destroystream;
NPNFuncs.status = pFuncs->status;
NPNFuncs.uagent = pFuncs->uagent;
NPNFuncs.memalloc = pFuncs->memalloc;
NPNFuncs.memfree = pFuncs->memfree;
NPNFuncs.memflush = pFuncs->memflush;
NPNFuncs.reloadplugins = pFuncs->reloadplugins;
NPNFuncs.getJavaEnv = pFuncs->getJavaEnv;
NPNFuncs.getJavaPeer = pFuncs->getJavaPeer;
NPNFuncs.getvalue = pFuncs->getvalue;
NPNFuncs.setvalue = pFuncs->setvalue;
NPNFuncs.invalidaterect = pFuncs->invalidaterect;
NPNFuncs.invalidateregion = pFuncs->invalidateregion;
NPNFuncs.forceredraw = pFuncs->forceredraw;
NPNFuncs.getstringidentifier = pFuncs->getstringidentifier;
NPNFuncs.getstringidentifiers = pFuncs->getstringidentifiers;
NPNFuncs.getintidentifier = pFuncs->getintidentifier;
NPNFuncs.identifierisstring = pFuncs->identifierisstring;
NPNFuncs.utf8fromidentifier = pFuncs->utf8fromidentifier;
NPNFuncs.intfromidentifier = pFuncs->intfromidentifier;
NPNFuncs.createobject = pFuncs->createobject;
NPNFuncs.retainobject = pFuncs->retainobject;
NPNFuncs.releaseobject = pFuncs->releaseobject;
NPNFuncs.invoke = pFuncs->invoke;
NPNFuncs.invokeDefault = pFuncs->invokeDefault;
NPNFuncs.evaluate = pFuncs->evaluate;
NPNFuncs.getproperty = pFuncs->getproperty;
NPNFuncs.setproperty = pFuncs->setproperty;
NPNFuncs.removeproperty = pFuncs->removeproperty;
NPNFuncs.hasproperty = pFuncs->hasproperty;
NPNFuncs.hasmethod = pFuncs->hasmethod;
NPNFuncs.releasevariantvalue = pFuncs->releasevariantvalue;
NPNFuncs.setexception = pFuncs->setexception;
browser = &NPNFuncs;
return NPERR_NO_ERROR;
}
NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pluginFuncs)
{
if(pluginFuncs == NULL)
return NPERR_INVALID_FUNCTABLE_ERROR;
if(pluginFuncs->size < sizeof(NPPluginFuncs))
return NPERR_INVALID_FUNCTABLE_ERROR;
pluginFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
pluginFuncs->size = sizeof(NPPluginFuncs);
pluginFuncs->newp = NPP_New;
pluginFuncs->destroy = NPP_Destroy;
pluginFuncs->setwindow = NPP_SetWindow;
pluginFuncs->newstream = NPP_NewStream;
pluginFuncs->destroystream = NPP_DestroyStream;
pluginFuncs->asfile = NPP_StreamAsFile;
pluginFuncs->writeready = NPP_WriteReady;
pluginFuncs->write = NPP_Write;
pluginFuncs->print = NPP_Print;
pluginFuncs->event = NPP_HandleEvent;
pluginFuncs->urlnotify = NPP_URLNotify;
pluginFuncs->getvalue = NPP_GetValue;
pluginFuncs->setvalue = NPP_SetValue;
pluginFuncs->javaClass = NULL;
return NPERR_NO_ERROR;
}
NPError OSCALL NP_Shutdown(void)
{
return NPERR_NO_ERROR;
}
NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved)
{
if (browser->version >= 14)
instance->pdata = browser->createobject (instance, getPluginClass());
return NPERR_NO_ERROR;
}
NPError NPP_Destroy(NPP instance, NPSavedData** save)
{
PluginObject *obj = (PluginObject *)instance->pdata;
return NPERR_NO_ERROR;
}
NPError NPP_SetWindow(NPP instance, NPWindow* window)
{
PluginObject *obj = (PluginObject *)instance->pdata;
// Do nothing if browser didn't support NPN_CreateObject which would have created the PluginObject.
if (obj != NULL) {
obj->window = window;
}
return NPERR_NO_ERROR;
}
NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
{
return NPERR_NO_ERROR;
}
NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
{
return NPERR_NO_ERROR;
}
int32 NPP_WriteReady(NPP instance, NPStream* stream)
{
return 0;
}
int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
{
return 0;
}
void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
{
}
void NPP_Print(NPP instance, NPPrint* platformPrint)
{
}
int16 NPP_HandleEvent(NPP instance, void* event)
{
return 0;
}
void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
{
}
NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
{
if(instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
if (variable == NPPVpluginScriptableNPObject) {
void **v = (void **)value;
PluginObject *obj = (PluginObject *)instance->pdata;
// Increase reference count
obj->referenceCount++;
*v = obj;
return NPERR_NO_ERROR;
}
return NPERR_GENERIC_ERROR;
}
NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
{
return NPERR_GENERIC_ERROR;
}
I don't know if this is enough information to even diagnose the problem, but any help would be much appreciated. If anyone wants to look at the full source code for this plugin it is available in your Maya install directory (if you have Maya, of course) in devkit/externalwebbrowser/windows

JCuda. Reusing already used pointer

I have a trouble working with JCUDA. I have a task to make 1D FFT using CUFFT library, but the result should be multiply on 2. So I decided to make 1D FFT with type CUFFT_R2C. Class responsible for this going next:
public class FFTTransformer {
private Pointer inputDataPointer;
private Pointer outputDataPointer;
private int fftType;
private float[] inputData;
private float[] outputData;
private int batchSize = 1;
public FFTTransformer (int type, float[] inputData) {
this.fftType = type;
this.inputData = inputData;
inputDataPointer = new CUdeviceptr();
JCuda.cudaMalloc(inputDataPointer, inputData.length * Sizeof.FLOAT);
JCuda.cudaMemcpy(inputDataPointer, Pointer.to(inputData),
inputData.length * Sizeof.FLOAT, cudaMemcpyKind.cudaMemcpyHostToDevice);
outputDataPointer = new CUdeviceptr();
JCuda.cudaMalloc(outputDataPointer, (inputData.length + 2) * Sizeof.FLOAT);
}
public Pointer getInputDataPointer() {
return inputDataPointer;
}
public Pointer getOutputDataPointer() {
return outputDataPointer;
}
public int getFftType() {
return fftType;
}
public void setFftType(int fftType) {
this.fftType = fftType;
}
public float[] getInputData() {
return inputData;
}
public int getBatchSize() {
return batchSize;
}
public void setBatchSize(int batchSize) {
this.batchSize = batchSize;
}
public float[] getOutputData() {
return outputData;
}
private void R2CTransform() {
cufftHandle plan = new cufftHandle();
JCufft.cufftPlan1d(plan, inputData.length, cufftType.CUFFT_R2C, batchSize);
JCufft.cufftExecR2C(plan, inputDataPointer, outputDataPointer);
JCufft.cufftDestroy(plan);
}
private void C2CTransform(){
cufftHandle plan = new cufftHandle();
JCufft.cufftPlan1d(plan, inputData.length, cufftType.CUFFT_C2C, batchSize);
JCufft.cufftExecC2C(plan, inputDataPointer, outputDataPointer, fftType);
JCufft.cufftDestroy(plan);
}
public void transform(){
if (fftType == JCufft.CUFFT_FORWARD) {
R2CTransform();
} else {
C2CTransform();
}
}
public float[] getFFTResult() {
outputData = new float[inputData.length + 2];
JCuda.cudaMemcpy(Pointer.to(outputData), outputDataPointer,
outputData.length * Sizeof.FLOAT, cudaMemcpyKind.cudaMemcpyDeviceToHost);
return outputData;
}
public void releaseGPUResources(){
JCuda.cudaFree(inputDataPointer);
JCuda.cudaFree(outputDataPointer);
}
public static void main(String... args) {
float[] inputData = new float[65536];
for(int i = 0; i < inputData.length; i++) {
inputData[i] = (float) Math.sin(i);
}
FFTTransformer transformer = new FFTTransformer(JCufft.CUFFT_FORWARD, inputData);
transformer.transform();
float[] result = transformer.getFFTResult();
HilbertSpectrumTicksKernelInvoker.multiplyOn2(transformer.getOutputDataPointer(), inputData.length+2);
transformer.releaseGPUResources();
}
}
Method which responsible for multiplying uses cuda kernel function.
Java method code:
public static void multiplyOn2(Pointer inputDataPointer, int dataSize){
// Enable exceptions and omit all subsequent error checks
JCudaDriver.setExceptionsEnabled(true);
// Create the PTX file by calling the NVCC
String ptxFileName = null;
try {
ptxFileName = FileService.preparePtxFile("resources\\HilbertSpectrumTicksKernel.cu");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Initialize the driver and create a context for the first device.
cuInit(0);
CUdevice device = new CUdevice();
cuDeviceGet(device, 0);
CUcontext context = new CUcontext();
cuCtxCreate(context, 0, device);
// Load the ptx file.
CUmodule module = new CUmodule();
cuModuleLoad(module, ptxFileName);
// Obtain a function pointer to the "add" function.
CUfunction function = new CUfunction();
cuModuleGetFunction(function, module, "calcSpectrumSamples");
// Set up the kernel parameters: A pointer to an array
// of pointers which point to the actual values.
int N = (dataSize + 1) / 2 + 1;
int pair = (dataSize + 1) % 2 > 0 ? 1 : -1;
Pointer kernelParameters = Pointer.to(Pointer.to(inputDataPointer),
Pointer.to(new int[] { dataSize }),
Pointer.to(new int[] { N }), Pointer.to(new int[] { pair }));
// Call the kernel function.
int blockSizeX = 128;
int gridSizeX = (int) Math.ceil((double) dataSize / blockSizeX);
cuLaunchKernel(function, gridSizeX, 1, 1, // Grid dimension
blockSizeX, 1, 1, // Block dimension
0, null, // Shared memory size and stream
kernelParameters, null // Kernel- and extra parameters
);
cuCtxSynchronize();
// Allocate host output memory and copy the device output
// to the host.
float freq[] = new float[dataSize];
cuMemcpyDtoH(Pointer.to(freq), (CUdeviceptr)inputDataPointer, dataSize
* Sizeof.FLOAT);
And the kernel function is next:
extern "C"
__global__ void calcSpectrumSamples(float* complexData, int dataSize, int N, int pair) {
int i = threadIdx.x + blockIdx.x * blockDim.x;
if(i >= dataSize) return;
complexData[i] = complexData[i] * 2;
}
But when I'm trying to pass the pointer which points to the result of FFT (in device memory) to the multiplyOn2 method, it throws the exception on cuCtxSynchronize() call. Exception:
Exception in thread "main" jcuda.CudaException: CUDA_ERROR_UNKNOWN
at jcuda.driver.JCudaDriver.checkResult(JCudaDriver.java:263)
at jcuda.driver.JCudaDriver.cuCtxSynchronize(JCudaDriver.java:1709)
at com.ifntung.cufft.HilbertSpectrumTicksKernelInvoker.multiplyOn2(HilbertSpectrumTicksKernelInvoker.java:73)
at com.ifntung.cufft.FFTTransformer.main(FFTTransformer.java:123)
I was trying to do the same using Visual Studion C++ and there no problems with this. Could you please help me.
P.S.
I can solve this prolem, but I need to copy data from device memory to host memory and then copy back with creating new pointers every time before calling new cuda functions, which slows my program executing.
Where exactly does the error occurs at which line?
The Cuda error can also be a previous error.
Why do you use Pointer.to(inputDataPointer), you already have that device pointer. Now you pass a pointer to the device pointer to the device?
Pointer kernelParameters = Pointer.to(Pointer.to(inputDataPointer),
I also recommend to use "this" qualifier or any other marking to detect instance variables. I hate and refuse to look through code, especially as nested and long as your example if I cannot see which scope the variable in methods have trying to debug it by just reading it.
I don't wanna ask myself always where the hell comes this variable from.
If a complex code in a question at SO is not formatted properly I don't read it.

How to use std::find/std::find_if with a vector of custom class objects?

I have a class representing a user called Nick and I want to use std::find_if on it, where I want to find if the userlist vector has an object included with the same username I pass in. I did a few attempts by trying to create a new Nick object for the username I want to test and overloading the == operator and then trying to use find/find_if on the object:
std::vector<Nick> userlist;
std::string username = "Nicholas";
if (std::find(userlist.begin(), userlist.end(), new Nick(username, false)) != userlist.end())) {
std::cout << "found";
}
I have overloaded the == operator so comparing Nick == Nick2 should work, but the function returns error C2678: binary '==' : no operator found which takes a left-hand operand of type 'Nick' (or there is no acceptable conversion).
Here is my Nick class for reference:
class Nick {
private:
Nick() {
username = interest = email = "";
is_op = false;
};
public:
std::string username;
std::string interest;
std::string email;
bool is_op;
Nick(std::string d_username, std::string d_interest, std::string d_email, bool d_is_op) {
Nick();
username = d_username;
interest = d_interest;
email = d_email;
is_op = d_is_op;
};
Nick(std::string d_username, bool d_is_op) {
Nick();
username = d_username;
is_op = d_is_op;
};
friend bool operator== (Nick &n1, Nick &n2) {
return (n1.username == n2.username);
};
friend bool operator!= (Nick &n1, Nick &n2) {
return !(n1 == n2);
};
};
If you are using C++0X you can use a simple lambda expression
std::string username = "Nicholas";
std::find_if(userlist.begin(), userlist.end(), [username](Nick const& n){
return n.username == username;
})
You have to define operator== with two Objects outside your class, as a tool function, not a member.
Then to make it friend just put the declaration of the function inside the class.
try something like this:
class Nick {
public:
friend bool operator== ( const Nick &n1, const Nick &n2);
};
bool operator== ( const Nick &n1, const Nick &n2)
{
return n1.username == n2.username;
}
Also your find should look like this:
std::find(userlist.begin(), userlist.end(), Nick(username, false) );
No need of "new".
I know that you wanted to overload the == operator, but the same thing can easily be done with a predicate:
struct UsernameIs {
UsernameIs( string s ) : toFind(s) { }
bool operator() (const Nick &n)
{ return n.username == toFind; }
string toFind;
};
int main()
{
vector<Nick> vn(10);
string nameToFind = "something";
find_if(vn.begin(), vn.end(), UsernameIs(nameToFind));
}
Note that in C++0x, you can do the same thing with a lambda expression much more concisely.
You are passing a pointer to the find function. Drop the new:
std::find(userlist.begin(), userlist.end(), Nick(username, false))
Also, your operators should accept their arguments by const reference, they don't modify them.
bool operator== (const Nick &n1, const Nick &n2)
I am noticing you are trying to call one constructor from another in this manner:
Nick(std::string d_username, bool d_is_op) {
Nick();
...
Well, sorry, but this doesn't work. The line Nick() just creates a temporary and doesn't affect this. Constructor forwarding is only possible in C++0x (the upcoming standard)
As to your problem - this question asked a couple of days ago about binary_search covers the same grounds. The top answer is just awesome.
Mystical restriction on std::binary_search
HTH.
P.S. Ideally this should have been a comment, but it's just too verbose
You can use boost::bind
std::find_if( userlist.begin(), userlist.end(),
boost::bind( & Nick::isFound,
_1 ) );
just implement bool Nick::isFound()
You can also pass the criteria
std::find_if( userlist.begin(), userlist.end(),
boost::bind( & Nick::compare,
_1,
nick ) );
implement
bool Nick::compare( const Nick & nick )
{
return this->username == nick.username;
}
This works for me:
Nick.h
#include <string>
class Nick {
private:
Nick() {
username = interest = email = "";
is_op = false;
};
public:
std::string username;
std::string interest;
std::string email;
bool is_op;
Nick(std::string d_username, std::string d_interest, std::string d_email, bool d_is_op) {
Nick();
username = d_username;
interest = d_interest;
email = d_email;
is_op = d_is_op;
};
Nick(std::string d_username, bool d_is_op) {
Nick();
username = d_username;
is_op = d_is_op;
};
bool operator==(const Nick& refNick) const
{
if (username != refNick.username)
return false;
if (interest != refNick.interest)
return false;
if (email != refNick.email)
return false;
if (is_op != refNick.is_op)
return false;
return true;
}
bool operator!=(const Nick& refNick) const
{
if (username == refNick.username)
return true;
if (interest == refNick.interest)
return true;
if (email == refNick.email)
return true;
if (is_op == refNick.is_op)
return true;
return false;
}
};
main.cpp
#include <iostream>
#include <string>
#include <vector>
#include "Nick.h"
int main()
{
std::vector<Nick> userlist;
std::string username = "Nicholas";
Nick Nicholas(username, false);
Nick John("John", true);
userlist.push_back(Nicholas);
std::vector<Nick>::iterator it;
it = std::find(userlist.begin(), userlist.end(), Nick("Nicholas", false));
if(it != userlist.end())
std::cout << "\n" << Nicholas.username << " was found.";
else
std::cout << "\n" << Nicholas.username << " was not found.";
it = std::find(userlist.begin(), userlist.end(), John);
if (it != userlist.end())
std::cout << "\n" << John.username << " was found.";
else
std::cout << "\n" << John.username << " was not found.";
}
Result
Nicholas was found.
John was not found.