1

I want to find the type from a list I can construct with a template parameter. In this example:

using my_type = typename get_constructible<char *, int, std::string>::type;

my_type must be std::string because in the list std::string is the first that can be constructed with a char *.

I tried this:

#include <string>
#include <utility>

template<typename T, typename... Rest>
struct get_constructible
{
  using type = void;
};

template<typename T, typename First, typename... Rest>
struct get_constructible<T, First, Rest...>
{
  using type = typename std::conditional<
    std::is_constructible<First, T>::value,
    First,
    get_constructible<T, Rest...>::type
  >::type;
};

int main(void)
{
  using my_type = get_constructible<char *, int, std::string>::type;
  my_type s("Hi!");
}

I do not understand where my logic fails.

Boiethios
  • 38,438
  • 19
  • 134
  • 183

1 Answers1

7

Your logic looks fine, but you're missing a typename on the dependent name get_constructible<T, Rest...>::type:

using type = typename std::conditional<
  std::is_constructible<First, T>::value,
  First,
  typename get_constructible<T, Rest...>::type
//^^^^^^^^
>::type;
TartanLlama
  • 63,752
  • 13
  • 157
  • 193
  • 4
    clang error: "error: template argument for template type parameter must be a type; **did you forget 'typename'?**" – bolov Nov 04 '16 at 15:11
  • 1
    That's why I compile with both gcc and clang when I don't quickly understand an error. One of them could hold my hand, like in this example. – bolov Nov 04 '16 at 15:15
  • @bolov I compile under vsc++ and the error messages are all but helpful… I am under ms windows and I know nothing about this OS (I don't know how to install clang). Aside from that, I am tired of those things in c++: I cannot understand the `typename` rules. – Boiethios Nov 04 '16 at 15:23
  • 1
    @Boiethios Have a read of [this answer](http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords). Essentially, if the type depends on a template parameter, then you need `typename`. – TartanLlama Nov 04 '16 at 15:24
  • @Boiethios when you have a MCVE like this one a convenient solution is to try it in an online compiler e.g. http://gcc.godbolt.org/ (don't know why I can't create a link with your code, anyway basically paste your code and select the latest gcc or clang from the compiler dropdown) – bolov Nov 04 '16 at 15:29
  • @bolov I think the UI changed, sharing links is now the second toolbar icon from the right on the source code pane. – TartanLlama Nov 04 '16 at 15:34
  • @bolov Thanks, the site is in my favorites now ;) I compiled under clang++ at school before, and I prefer by far its messages. – Boiethios Nov 04 '16 at 15:34