White RoomNEW

The Greedy Constructor

#include <iostream>
#include <string>
#include <utility>

class Session {
public:
    template <class T>
    explicit Session(T&& id) : id_(std::forward<T>(id)) { std::cout << "tmpl "; }

    Session(const Session& o) : id_(o.id_) { std::cout << "copy "; }

private:
    std::string id_;
};

int main() {
    const Session a{std::string("abc")};   // prints "tmpl "
    Session b{a};         // (1) compiles, prints "copy"
    const Session c{a};   // (2) compiles, prints "copy"
    Session d{b};         // (3) does NOT compile
}

Line (3) is rejected with an error about constructing std::string from Session, and the diagnostic blames an instantiation of Session::Session<Session&>. Why does it fail when (1) and (2) succeed?