I have begun a project that makes heavy use of c++20 concepts as a way of learning some of the new c++20 features. As part of it, I have a function template that takes a single argument and operates on it. I wish to have the flexibility to pass types to this function that specify another type that they operate on, but that defaults to something else if that specification doesn't exist.

For example, here is a type that specifies a type that it operates on:

```
struct has_typedef_t
{
    typedef int my_type; //operates on this type
    void use_data(const my_type& data) const
    {
         //do something else
    }
};

```

and one that does not specify a type, but operates on a default type specified elsewhere:

```
typedef std::string default_type;
struct has_no_typedef_t
{
    void use_data(const default_type& data) const
    {
        //do something
    }
};

```

I have a simple concept that can tell me if any given type has this specification:

```
template <class T> concept has_type = requires(T t) {typename T::my_type;};

```

And the function might look something like the following:

```
template <class T> void my_function(const T& t)
{
    //Here I want a default-constructed value of the default
    //type if the argument doesn't have a typedef
    typename std::conditional<has_type<T>, typename T::my_type, default_type>::type input_data;
    t.use_data(input_data);
}

```

The problem here is that the second template argument is invalid for anything that doesn't specify a type, e.g. `has_no_typedef_t`. An example program:

```
int main(int argc, char** argv)
{
    has_no_typedef_t s1;
    has_typedef_t    s2;

    // my_function(s1); // doesn't compile:
    //'has_no_typedef_t has no type named 'my_type'

    my_function(s2); //compiles
    return 0;
}

```

What I am looking for is a replacement for the following line:

```
typename std::conditional<has_type<T>, typename T::my_type, default_type>::type input_data;

```

as this is causing the problem. I am aware that I can pull of some tricks using an overloaded function using the concept above and combining decltype and declval, but I am looking for something clean and have not been able to come up with anything. How can I achieve this behavior cleanly?

Below is the full code for the full picture (c++20):

```
#include <iostream>
#include <type_traits>
#include <concepts>
#include <string>

template <class T> concept has_type = requires(T t) {typename T::my_type;};

struct has_typedef_t
{
    typedef int my_type;
    void use_data(const my_type& data) const
    {
        //do something
    }
};

typedef std::string default_type;
struct has_no_typedef_t
{
    void use_data(const default_type& data) const
    {
        //do something else
    }
};

template <class T> void my_function(const T& t)
{
    //Here I want a default-constructed value of the default
    //type if the argument doesn't have a typedef
    typename std::conditional<has_type<T>, typename T::my_type, default_type>::type input_data;
    t.use_data(input_data);
}

int main(int argc, char** argv)
{
    has_no_typedef_t s1;
    has_typedef_t    s2;

    // my_function(s1); // doesn't compile:
    //'has_no_typedef_t has no type named 'my_type'

    my_function(s2); //compiles
    return 0;
}

```