From: jrwats on
So we have this templated factory for COM objects. A simplistic view
of it would be the following:

template <class T>
class Creator
{
public:
// const& arguments
template <class I>
static HRESULT Create(I** ppI)
{
return Create(NoArg(), NoArg(), NoArg(), NoArg(), NoArg(),
NoArg(), NoArg(), NoArg(), ppI);
}

template <class TArg1, class I>
static HRESULT Create(TArg1 t1, __deref_out I** ppI)
{
return Create(t1, NoArg(), NoArg(), NoArg(), NoArg(),
NoArg(), NoArg(), NoArg(), ppI);
}

// Handle Arguments 2 - 7 as above

template <class TArg1, class TArg2, class TArg3, class TArg4,
class TArg5,
class TArg6, class TArg7, class TArg8, class I>
static HRESULT Create(TArg1 t1, TArg2 t2, TArg3 t3, TArg4 t4,
TArg5 t5,
TArg6 t6, TArg7 t7, TArg8 t8, I** ppI)
{
HRESULT hr = S_OK;
T* pT = NULL;

// Creation code here...

if (hr >= 0)
{
hr = __Init(pT, t1, t2, t3, t4, t5, t6, t7, t8);
}
else
{
return E_OUTOFMEMORY;
}

if (hr >= 0)
{
*ppI = pT;
hr = S_OK;
}

return hr;
}

template <class TArg1, class TArg2, class TArg3, class TArg4,
class TArg5,
class TArg6, class TArg7, class TArg8>
static HRESULT __Init(__in T* pT, TArg1 t1, TArg2 t2, TArg3 t3,
TArg4 t4,
TArg5 t5, TArg6 t6, TArg7 t7, TArg8 t8)
{
return pT->Initialize(t1, t2, t3, t4, t5, t6, t7, t8);
}

template <class TArg1, class TArg2, class TArg3, class TArg4,
class TArg5,
class TArg6, class TArg7>
static HRESULT __Init(__in T* pT, TArg1 t1, TArg2 t2, TArg3 t3,
TArg4 t4,
TArg5 t5, TArg6 t6, TArg7 t7, NoArg)
{
return pT->Initialize(t1, t2, t3, t4, t5, t6, t7);
}

// handle Arguments 6 - 0 via template specialization as above
};


The problem is passing in an instance of some class CFoo calls the
copy constructor. And if I make all the arguments const& then people
cannot do the following:

HRESULT (*PfnCreator)(ISomeInterface* pSomeInterface, IDesiredObject**
ppDesiredObject) =
*ComCreator<CDesiredObject>::Create;

Since the function signature is actually
HRESULT Create(ISomeInterface* const& pSomeInterface, IDesiredObject**
ppDesiredObject);

So I'd like to avoid this as I'd hate for callers to have to go do
this.

I also can't defineCreate as follows

template <class TArg1, class I>
static HRESULT Create(TypeTraits<TArg1>::ParameterType t1,
__deref_out I** ppI)
{
return Create(t1, NoArg(), NoArg(), NoArg(), NoArg(),
NoArg(), NoArg(), NoArg(), ppI);
}

As this simply can't work since template argument deduction has
already happened to determine the type of TArg1.

Are there any other solutions so this? Again I do *not* want an
ubiquitous const&.

Thanks!

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: McNepp on
I faced a similiar problem when I wrote a template library to ease the
use of the JNI.
My solution was: Make the function's parameter types part of the class
template, providing 'void' as default types for
non-existing arguments. Then, partially specialize the class. With
that scheme, you can apply type traits to the parameters!
Here's a rough sketch, using a maximum of 2 parameters:

// Primary template, will never be used with void for A1 or A2
template<class T,class A1=void,class A2=void> class Creator<T,A1,A2>
{
public:
template<typename I> static HRESULT Create(I** ppI,
TypeTraits<A1>::ParameterType a1, TypeTraits<A2>::ParameterType a2)
{
}
};


template<class T> class Creator<T,void,void>
{
public:
template<typename I> static HRESULT Create(I** ppI)
{
}
};

template<class T,class A1> class Creator<T,A1,void>
{
public:
template<typename I> static HRESULT Create(I** ppI,
TypeTraits<A1>::ParameterType a1)
{
}
};



On 27 Mai, 09:38, jrwats <jrw...(a)gmail.com> wrote:
> So we have this templated factory for COM objects. A simplistic view
> of it would be the following:
>
> template <class T>
> class Creator
> {
> public:
> // const& arguments
> template <class I>
> static HRESULT Create(I** ppI)
> {
> return Create(NoArg(), NoArg(), NoArg(), NoArg(), NoArg(),
> NoArg(), NoArg(), NoArg(), ppI);
> }
>
> template <class TArg1, class I>
> static HRESULT Create(TArg1 t1, __deref_out I** ppI)
> {
> return Create(t1, NoArg(), NoArg(), NoArg(), NoArg(),
> NoArg(), NoArg(), NoArg(), ppI);
> }
>
> // Handle Arguments 2 - 7 as above
>
> template <class TArg1, class TArg2, class TArg3, class TArg4,
> class TArg5,
> class TArg6, class TArg7, class TArg8, class I>
> static HRESULT Create(TArg1 t1, TArg2 t2, TArg3 t3, TArg4 t4,
> TArg5 t5,
> TArg6 t6, TArg7 t7, TArg8 t8, I** ppI)
> {
> HRESULT hr = S_OK;
> T* pT = NULL;
>
> // Creation code here...
>
> if (hr >= 0)
> {
> hr = __Init(pT, t1, t2, t3, t4, t5, t6, t7, t8);
> }
> else
> {
> return E_OUTOFMEMORY;
> }
>
> if (hr >= 0)
> {
> *ppI = pT;
> hr = S_OK;
> }
>
> return hr;
> }
>
> template <class TArg1, class TArg2, class TArg3, class TArg4,
> class TArg5,
> class TArg6, class TArg7, class TArg8>
> static HRESULT __Init(__in T* pT, TArg1 t1, TArg2 t2, TArg3 t3,
> TArg4 t4,
> TArg5 t5, TArg6 t6, TArg7 t7, TArg8 t8)
> {
> return pT->Initialize(t1, t2, t3, t4, t5, t6, t7, t8);
> }
>
> template <class TArg1, class TArg2, class TArg3, class TArg4,
> class TArg5,
> class TArg6, class TArg7>
> static HRESULT __Init(__in T* pT, TArg1 t1, TArg2 t2, TArg3 t3,
> TArg4 t4,
> TArg5 t5, TArg6 t6, TArg7 t7, NoArg)
> {
> return pT->Initialize(t1, t2, t3, t4, t5, t6, t7);
> }
>
> // handle Arguments 6 - 0 via template specialization as above
>
> };
>
> The problem is passing in an instance of some class CFoo calls the
> copy constructor. And if I make all the arguments const& then people
> cannot do the following:
>
> HRESULT (*PfnCreator)(ISomeInterface* pSomeInterface, IDesiredObject**
> ppDesiredObject) =
> *ComCreator<CDesiredObject>::Create;
>
> Since the function signature is actually
> HRESULT Create(ISomeInterface* const& pSomeInterface, IDesiredObject**
> ppDesiredObject);
>
> So I'd like to avoid this as I'd hate for callers to have to go do
> this.
>
> I also can't defineCreate as follows
>
> template <class TArg1, class I>
> static HRESULT Create(TypeTraits<TArg1>::ParameterType t1,
> __deref_out I** ppI)
> {
> return Create(t1, NoArg(), NoArg(), NoArg(), NoArg(),
> NoArg(), NoArg(), NoArg(), ppI);
> }
>
> As this simply can't work since template argument deduction has
> already happened to determine the type of TArg1.
>
> Are there any other solutions so this? Again I do *not* want an
> ubiquitous const&.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]