6

what template <class = typename T::type> means? Can you refer me to some blog, specification describing this?

The question originaly came from explanation of sfinae on cpp reference

template <typename A>
struct B { typedef typename A::type type; };

template <
  class T,
  class   = typename T::type,      // SFINAE failure if T has no member type
  class U = typename B<T>::type    // hard error if T has no member type
                                   // (guaranteed to not occur as of C++14)
> void foo (int);
2
  • 6
    class = typename T::type is a template parameter with no name, but with a default value. Commented Mar 21, 2018 at 14:01
  • 7
    its an anonymous parameter whose only purpose is to render the template invalid in case T has no type Commented Mar 21, 2018 at 14:02

1 Answer 1

19

First, I'll explain typename T::type. This is simply the access of a member type. Here's an example of accessing a member type:

struct foo {
    using bar = int;
};

int main() {
    foo::bar var{};

    // var has type int
}

So why the typename? It simply means we want to access a type. Since we are in a template and T is an unknown type, and foo::bar could also mean accessing a static variable. To disambiguate, we denote that we effectively want to access a type by explicitly typing typename.

Okay, now what does the class = means?

The class = means the same thing as typename =. When declaring template type parameters, we introduce then using class or typename:

template<typename A, typename B>
struct baz {};

But as any parameters in C++, the name is optional. I could have wrote this and the following is completely equivalent:

template<typename, typename>
struct baz {};

Also, you know in function parameters, we can specify default values? Like that:

void func(int a, int b = 42);

int main () {
    func(10); // parameter b value is 42
              // We are using default value
}

We can also omit parameter names:

void func(int, int = 42);

Just like function parameters, template parameters can have it's name omitted, and can have a default value.

template<typename, typename = float>
struct baz {};

baz<int> b; // second parameter is float

Putting it all together

Now we have this declaration:

template <
    class T,
    class   = typename T::type,   // SFINAE failure if T has no member type
    class U = typename B<T>::type // hard error if T has no member type
                                  // (guaranteed to not occur as of C++14)
> void foo (int);

Here we declare a function that takes an int as parameter, and has three template parameter.

The fist parameter is a simple named parameter. The name is T and it's a type template parameter. The second is also a type parameters, but it has no name. However, it has a default value of T::type, which is a member type of T. We are explicitly telling the compiler that T::type must be a member type of T by specifying typename. The third parameter is similar to the second.

This is where SFINAE kicks in: when a default parameter is used, but T::type as as a member type don't exist, how can you assign the second template parameter to that? We can't. If T::type don't exists, we cannot assign the second template parameter. But instead of making it an error, the compiler will simply try another function, because there is a chance another function would be callable.

This is quite similar to simple overloading. You have the f function. It takes a float parameter, an another overload that takes a std::string. Imagine you call f(9.4f). Does the compiler choke because a std::string is not constructible from a float? No! The compiler ain't stupid. It will try another overload, and will find the float version and call it. In SFINAE a similar analogy can be made. The compiler won't stop because there's some overload somewhere that needs an undefined type in a template parameter. It will try another overload.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.