Home > other >  how to provide a default value for a template conditional type?
how to provide a default value for a template conditional type?

Time:09-16

All

I am writing a trimStart fucntion with c template like the following:

template<typename T>
static T trimStart(T source, const std::conditional<isWide<T>(), wchar_t, char>::type* trimChars = " \t\n\r\v\f"))
{
    ....
}

now I like to provide a default value " \t\n\r\v\f" or L" \t\n\r\v\f" according the type of trimChars, could you please help me look at how to implement for that?

CodePudding user response:

It should be possible to use different constants conditionally by using template specialization as sketched in this answer. You can create different classes and put separate compile time constants (or runtime functions) in them. At compile time, you select which one should be chosen (e.g. by specializing them with a boolean).

In C 17, you have constexpr if, which would simplify it. But since the question is tagged with C 14, I assume you cannot use it.

CodePudding user response:

I rearranged your code to this:

#include <type_traits>
#include <iostream>

template <typename T> struct is_foo : std::false_type {};
struct foo{ int value;};
template <> struct is_foo<foo> : std::true_type {};

struct bar{};


template <typename T>
void func(T t, std::conditional_t<is_foo<T>::value,int,double> x = ????) {
    std::cout << x << "\n";
}

int main() {
    func(foo{});
    func(bar{});
}

func takes a parameter of type T. Depending on a condition on this type the second argument type is decided among two types. In my code it is between int when is_foo<T> is true and double when is_foo<T> is false.

You can replace ?? with a call to a function template that returns the desired default argument:

template <typename T,typename = void>
struct get_default{ 
    double operator()(){ return 42;}
};

template <typename T>
struct get_default<T,std::enable_if<is_foo<T>::value>> {
    double operator()(){ return 4.2; }
};

Complete Example

In your specific case I would consider to simply use std::string<T>.

  • Related