简体   繁体   中英

Template function specialization vs. Dummy input variable?

I have a factory method pattern used to create classes and I'd like to validate the input parameters before proceeding to the actual creation. There are two classes that I am dealing with here, A and B, and they each have their own validation. Given that I am already passing the class type (A or B) in my creation template function, I'd like to use that type directly to tell which validation I need to use. I am considering to use template function specialization or dummy input parameter to do that, each with their own pros/cons. Please let me know if either one of them looks more reasonable, or if there are other options too. Thanks!

Oh, and I did consider making the validation as static methods of A or B, but that was not looking good because I am dealing with legacy code and moving that stuff around isn't too straightforward. I also showed this as an option below for completeness-sake though.

Template function specialization:

Pro: Able to use type passed into the FactoryCreateClass method directly for choosing validation

Con: Template method isn't being leveraged since there are only specializations

template <typename T>
void FactoryCreateClass (int, double)
(
    bool bSuccess = ValidateBlock<T>(int, double);

    if (bSuccess)
        T* = T::CreateInstance();           
)

template <typename T>
bool ValidateBlock (int double);    // don't need an implementation here since 
                                    // all specialization require different validation

template <>
bool ValidateBlock<A> (int, double)
{
    //do validation before creating A
}

template <>
bool ValidateBlock<B> (int, double)
{
    //do validation before creating B
}

Dummy Variable:

Pro: Able to use type passed into the FactoryCreateClass method directly for choosing validation

Con: Unused dummy variable

template <typename T>
void FactoryCreateClass (int, double)
(
    bool bSuccess = ValidateBlock(T /*dummy*/, int, double);

    if (bSuccess)
        T* = T::CreateInstance();           
)

bool ValidateBlock (A/*dummy*/, int, double)
{
    //do validation before creating A
}

bool ValidateBlock (B/*dummy*/, int, double)
{
    //do validation before creating B
}   

Static class method:

Pro: Able to use type passed into the FactoryCreateClass method directly for choosing validation

Con: Harder to make this type of change in legacy code

template <typename T>
void FactoryCreateClass (int, double)
(
    bool bSuccess = T::ValidateBlock(int, double);

    if (bSuccess)
        T* = T::CreateInstance();           
)

static bool A::ValidateBlock (int, double)
{
    //do validation before creating A
}

static bool B::ValidateBlock (int, double)
{
    //do validation before creating B
}

You have forgotten a third alternative: using traits.

template <typename> struct Trait;

template <>
struct Trait<A> {
    static bool Validate(int, double);
};

template <>
struct Trait<B> {
    static bool Validate(int, double);
};

And then:

template <typename T>
void FactoryCreateClass(int i, double d) {
    bool const success = Trait<T>::Validate(i, d);
    // ...
}

But of course, the real question is why not doing the validation in CreateInstance directly ?

The most appropriate design here is to do the validation inside the CreateInstance method, because the tasks (args validation and instance creation) are strongly coupled, and it is much more readable to have these to things together in one place.

However, it may be the case, you cannot change the code of the CreateInstance method. Well, then I see no significant difference between using function template or dummy variable. The latter is , however, a bit more explicit and thus more readable.

By the way, an unreferenced variable is really not a big problem, you can suppress it, see Disable single warning error , search for UNREFERENCED_PARAMETER on the page

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM