"Can anyone say why I get this error message that indicates that it has been defined twice?"
There error you posted has nothing to do with simple header issues if this is a method defined inside a template class. (You would get different errors... and a lot of them.)
Play with the extra source I've posted.
"Move the operators outside of the class."
That will directly solve nothing, but he may solve this issue as a side effect of moving the definitions. You are allowed to do what he has attempted; he has only done it wrong in some fashion.
"I'm confused..."
You did it wrong. See the source...
"But they do not help."
Why would it? You are still doing it wrong. Worse, you've already modified your source and may not solve the original problem.
Also, please learn to reduce your code to the smallest sample that results in the problem you need help with... I've obviously had to remove the Boost stuff and the 64 bit stuff.
Soma
Code:
#include <iostream>
#include "test.h"
#include "test2.h"
int main2();
int main()
{
test<int> a, b;
test2<int> c, d;
a == b;
c == d;
main2();
return(0);
}
Code:
#include <iostream>
#include "test.h"
#include "test2.h"
int main2()
{
test<int> a, b;
test2<int> c, d;
a == b;
c == d;
return(0);
}
Code:
template
<
unsigned long bits
>
struct nothing
{
};
template
<
typename T,
template <unsigned long> class ignored = nothing,
unsigned long bits = 32
>
struct test
{
template
<
typename TN,
typename UN
>
friend bool operator ==
(
const test<TN> & lhs,
const test<UN> & rhs
)
{
std::cout << "test\n";
return(true);
}
template
<
typename TN,
typename UN
>
friend bool operator ==
(
const test<TN> & lhs,
const test<UN> & rhs
)
{
std::cout << "test\n";
return(true);
}
};
Code:
template
<
unsigned long bits
>
struct nothing2
{
};
template
<
typename T,
template <unsigned long> class ignored = nothing2,
unsigned long bits = 32
>
struct test2;
template
<
typename TN,
typename UN
>
bool operator ==
(
const test2<TN> & lhs,
const test2<UN> & rhs
);
template
<
typename T,
template <unsigned long> class ignored,
unsigned long bits
>
struct test2
{
template<typename TN, typename UN>
friend bool operator == <> (const test2<TN> & lhs, const test2<UN>& rhs);
private: int i;
};
template
<
typename TN,
typename UN
>
bool operator ==
(
const test2<TN> & lhs,
const test2<UN> & rhs
)
{
std::cout << "test2\n";
return(lhs.i == rhs.i);
}
Code:
#ifndef MAD_SHARED_PTR_175451_H
#define MAD_SHARED_PTR_175451_H
#include <windows.h>
#include <memory>
#include <assert.h>
const int nullptr = NULL;
template<typename T> T* mad_ptr_clone(const T* pOld) { }
template<typename T, bool Polymorphic> struct smad_ptr_int
{
static T* Clone(const T* pOld) { return pOld->Clone(); } // IsPolymorphic = yes
};
template<typename T> struct smad_ptr_int<T, false>
{
static T* Clone(const T* pOld) { return new T(*pOld); } // IsPolymorphic = no
};
template<int N> struct ptr_bits { /*typedef current_amount_of_bits_not_supported rf_type;*/ };
template<> struct ptr_bits<32> { typedef unsigned long rf_type; };
template<> struct ptr_bits<64> { typedef unsigned long long rf_type; };
template<int Bits> class ptr_thread_safe { };
template<> class ptr_thread_safe<32>
{
public:
static void Increment(void* p) { InterlockedIncrement((LONG*)p); }
static void Decrement(void* p) { InterlockedDecrement((LONG*)p); }
};
template<> class ptr_thread_safe<64>
{
public:
static void Increment(void* p) { InterlockedIncrement((LONG*)p); }
static void Decrement(void* p) { InterlockedDecrement((LONG*)p); }
};
template<int Bits> class ptr_thread_dangerous
{
public:
template<typename T> static void Increment(T* p) { (*p)++; }
template<typename T> static void Decrement(T* p) { (*p)--; }
};
template<typename T, template<int> class thread_safety = ptr_thread_dangerous, int Bits = 32> class mad_shared_ptr;
template<typename lhs_t, typename rhs_t>
bool operator == (const mad_shared_ptr<lhs_t>& lhs, const mad_shared_ptr<rhs_t>& rhs);
template<typename lhs_t, typename rhs_t>
bool operator != (const mad_shared_ptr<lhs_t>& lhs, const mad_shared_ptr<rhs_t>& rhs);
template<typename T, template<int> class thread_safety, int Bits> class mad_shared_ptr
{
protected:
typedef void (mad_shared_ptr::* bool_type)() const;
template<typename T, int Bits> struct sptr
{
template<typename T> class deleter_base { public: virtual void destroy(T* p) = 0; };
template<typename T, typename deleter_t> class deleter: public deleter_base<T>
{
public:
deleter(deleter_t delete_fnc): m_delete_fnc(delete_fnc) { }
virtual void destroy(T* p) { m_delete_fnc(p); }
private:
deleter_t m_delete_fnc;
};
sptr(): p(nullptr), RefCount(0), pDeleter(nullptr) { }
T* p;
typename ptr_bits<Bits>::rf_type RefCount;
deleter_base<T>* pDeleter;
};
typedef sptr<T, Bits> ptr_t;
public:
mad_shared_ptr(): m_ptr(nullptr) { }
template<typename Other> mad_shared_ptr(Other* p): m_ptr(nullptr) { *this = p; }
template<typename Other, typename Deleter> mad_shared_ptr(Other* p, Deleter delete_fnc): m_ptr(nullptr)
{
std::auto_ptr< ptr_t::deleter_base<T> > pDeleter( new ptr_t::deleter<T, Deleter>(delete_fnc) );
*this = p;
m_ptr->pDeleter = pDeleter.release();
}
mad_shared_ptr(const mad_shared_ptr& rhs): m_ptr(nullptr) { *this = rhs; }
template<typename Other> mad_shared_ptr(const mad_shared_ptr<Other>& rhs): m_ptr(nullptr) { *this = rhs; }
~mad_shared_ptr() { DecRefCount(m_ptr); }
bool unique() const { return (m_ptr->RefCount == 1); }
void make_unique()
{
if (unique())
return;
std::auto_ptr<ptr_t> pNewPtr(new ptr_t);
pNewPtr->p = mad_ptr_clone(m_ptr->p);
pNewPtr->RefCount = 1;
pNewPtr->pDeleter = m_ptr->pDeleter;
DecRefCount(m_ptr);
m_ptr = pNewPtr.release();
}
void release()
{
DecRefCount();
m_p = nullptr;
m_RefCount = nullptr;
m_deleter = nullptr;
}
template<typename Other> mad_shared_ptr& operator = (Other* rhs)
{
if (m_ptr && rhs == m_ptr->p)
return *this;
ptr_t* pOldPtr = m_ptr;
std::auto_ptr<ptr_t> pNewPtr(new ptr_t);
pNewPtr->p = rhs;
pNewPtr->RefCount++;
m_ptr = pNewPtr.release();
DecRefCount(pOldPtr);
return *this;
}
mad_shared_ptr& operator = (const mad_shared_ptr& rhs)
{
return operator = <T>(rhs);
}
template<typename Other> mad_shared_ptr& operator = (const mad_shared_ptr<Other>& rhs)
{
if (rhs == *this)
return *this;
DecRefCount(m_ptr);
m_ptr = rhs.m_ptr;
IncRefCount(m_ptr);
return *this;
}
T& operator * () const { assert(m_ptr); return *m_ptr->p; }
T* operator -> () const { assert(m_ptr); return m_ptr->p; }
template<typename lhs_t, typename rhs_t>
friend bool operator == <> (const mad_shared_ptr<lhs_t>& lhs, const mad_shared_ptr<rhs_t>& rhs);
template<typename lhs_t, typename rhs_t>
friend bool operator != <> (const mad_shared_ptr<lhs_t>& lhs, const mad_shared_ptr<rhs_t>& rhs);
operator bool_type() const
{
return m_ptr && m_ptr->p ? &mad_shared_ptr::this_type_does_not_support_comparisons : nullptr;
}
protected:
void IncRefCount(sptr<T, Bits>* ptr)
{
thread_safety<Bits>::Increment(&ptr->RefCount);
}
void DecRefCount(sptr<T, Bits>*& ptr)
{
if (ptr == nullptr)
return;
thread_safety<Bits>::Decrement(&ptr->RefCount);
if (ptr->RefCount == 0)
{
if (ptr->pDeleter)
ptr->pDeleter->destroy(ptr->p);
else
delete ptr->p;
delete ptr;
ptr = nullptr;
}
}
void this_type_does_not_support_comparisons() const {}
sptr<T, Bits>* m_ptr;
};
template<typename lhs_t, typename rhs_t>
bool operator == (const mad_shared_ptr<lhs_t>& lhs, const mad_shared_ptr<rhs_t>& rhs)
{
return (lhs.m_ptr == rhs.m_ptr);
}
template<typename lhs_t, typename rhs_t>
bool operator != (const mad_shared_ptr<lhs_t>& lhs, const mad_shared_ptr<rhs_t>& rhs)
{
return !(lhs == rhs);
}
#endif // MAD_SHARED_PTR_175451_H