c++c++17language-lawyertemplate-argument-deductionctad

Anonymous temporaries and class template argument deduction - gcc vs clang


Consider the following code snippet:

template <typename T>
struct foo
{
    foo(T) { }
};

int main()
{
    foo{0};
}

g++ 7 happily creates a temporary object of type foo, deducing T = int.

clang++ 5 and 6 refuse to compile the code:

error: expected unqualified-id
    foo{0};
       ^

live example on wandbox


Is this a clang bug, or is there something in the Standard that prevents class template argument deduction from kicking in for unnamed temporaries?


Solution

  • Clang bug (#34091)

    From [dcl.type.class.deduct]:

    A placeholder for a deduced class type can also be used in [...] or as the simple-type-specifier in an explicit type conversion (functional notation). A placeholder for a deduced class type shall not appear in any other context. [ Example:

    template<class T> struct container {
        container(T t) {}
        template<class Iter> container(Iter beg, Iter end);
    };
    
    template<class Iter>
    container(Iter b, Iter e) -> container<typename std::iterator_traits<Iter>::value_type>;
    std::vector<double> v = { /* ... */ };
    
    container c(7);                         // OK, deduces int for T
    auto d = container(v.begin(), v.end()); // OK, deduces double for T
    container e{5, 6};                      // error, int is not an iterator
    

    — end example ]