-1

I cannot find in c++ the difference between std::conditional< >::type and std::conditional_t< > .

When I compile

 using A = typename conditional< true, int, char>::type;                     
 using B = typename conditional_t< true, int, char>::type;     

an error: expected nested-name-specifier gets out. I was unable to use conditional and nest, while conditional_t seems to nest.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
George Kourtis
  • 2,381
  • 3
  • 18
  • 28
  • 4
    `std::conditional::type` and `std::conditional_t` are [the same thing](https://en.cppreference.com/w/cpp/types/conditional). Don't use `::type` with `std::conditional_t`; it's already been done. – Pete Becker Aug 15 '23 at 16:49
  • If I read [this](https://en.cppreference.com/w/cpp/types/conditional#helper_types) right, `std::conditional<>` and `std::conditional_t<>` should be the same, except that the version with the `_t` does not need a `::type` at the end. – Joel Aug 15 '23 at 16:49
  • 2
    TL;DR: alias templates like `std::conditional_t` weren't possible before C++11, so you had to manually access member aliases of a template as `std::conditional<...>::type`. Now that alias templates are a thing, you can use them to save some verbosity and complexity. There should be a duplicate stating as much somewhere... – Brian61354270 Aug 15 '23 at 16:55
  • Does this answer your question? [Why are C++11 type traits not alias templates?](https://stackoverflow.com/questions/9498444/why-are-c11-type-traits-not-alias-templates). The [top answer](https://stackoverflow.com/a/9501282/11082165) discusses why type traits didn't use alias templates from the start – Brian61354270 Aug 15 '23 at 16:59
  • #include #include #include #include using namespace std; using F = typename conditional< true, int, char>::type; using G = typename conditional_t< true, int, char>; using H = typename conditional_t< true, int, char>::type; int main(){ F f=658979; G g=4546; H h=654; return 0; } DOES NOT COMPILE for both cases of conditional_t. It says something about nested ... – George Kourtis Aug 15 '23 at 17:06
  • code in comments is not readable. If you actually wanted to ask a different question about different code you can open a new question – 463035818_is_not_an_ai Aug 15 '23 at 17:38
  • @GeorgeKourtis I understand [where this question is coming from](https://stackoverflow.com/a/76907233/7582247) and I tried to answer it in the comment section. What I did was `using X = typename conditional_t::type;` - which requires `A` and `B` to have a `type` defined. `X` will therefore be `typename A::type` or `typename B::type`. If `type` is missing from the selected type (`A` or `B`) there will be a compilation error - as you requested in that question. – Ted Lyngmo Aug 18 '23 at 13:13

2 Answers2

4

Due to a design flaw in C++ templates, it turns out that creating a helper alias for type-functions is useful.

So std::conditional<bool, A, B> is a type-function template. Its ::type is either A or B.

std::conditional_t<bool, A, B> is an helper alias that evaluates to std::conditional<bool, A, B>::type. In most contexts, doing ::type on std::conditional requires you disambiguate with a typename prefix so the compiler knows that ::type is a type and not a value - but std::conditional_t does this for you, as it is syntactically known to be a type without a typename.

In the C++ std library, almost all (and maybe all) templates with a ::type member now come with a helper _t template that does this, which makes a bunch of use nicer.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
2

std::conditional_t is just a helper alias. From cppreference:

template< bool B, class T, class F >
using conditional_t = typename conditional<B,T,F>::type;

On the same link you can also find the statement:

The behavior of a program that adds specializations for std::conditional is undefined.

The same is not true for type traits you write or that come with libraries. And then the crux is that the fact that some_trait::type is a type is only a convention. Nothing in the language forbids you to specialize some_trait such that type is a static member of type int whose value is 42.

And thats why you need to disambiguate the member alias type via typename (see When is the "typename" keyword necessary?). std::conditional_t on the other hand is a type alias. It can only be a type. Its a helper that makes the use of the trait more convenient.

std::conditional_t (usually) has no member alias type. It is an alias for the member alias type of std::conditional.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • The nesting error was caused from the superfluous typename ::type – George Kourtis Aug 15 '23 at 18:57
  • @GeorgeKourtis ah now I remember that the error message says something along the line of "no nested ...". Thats why code and error message should be in the question when the question is about broken code. Anyhow, this question is not about the code, its just the "nest" you mention that is a little confusing – 463035818_is_not_an_ai Aug 15 '23 at 19:34