jeudi 7 février 2019

C2447 when using braces for templated base-class initialization in templated class

I am depending on a library, the authors of which extensively used the brace-notation for invoking all constructors, as has been fondly advertised and recommended by a number of parties in recent years.

The library is mostly developed on Linux using gcc but aims at being cross-platform compatible and in my case is used on Windows using Visual Studio 2015.

If I try to build the library, I get a C2447 compiler error which arises when templates of templates use this brace-notation. I tried to illustrate my case with the following MWE.

#include <iostream>

template <typename T>
class A
{
public:
    A(T x);
    virtual ~A() = default;
    T getX();
private:
    T x;
};

template <typename T>
class B : public A<T>
{
public:
    B(T x);
};

template <typename T>
class C : public A<T>
{
public:
    C(T x);
};

template <typename T>
class D : public A<T>
{
public:
    D(T x);
};


int main(int argn, char** argc)
{
    A<int> a(42);
    B<int> b(42);
    C<int> c(42);
    D<int> d(42);
    std::cout << "A: " << a.getX() << std::endl
        << "B: " << b.getX() << std::endl
        << "C: " << c.getX() << std::endl
        << "D: " << d.getX() << std::endl;
    return 0;
}

template<typename T>
A<T>::A(T x) : x(x) {}

template<typename T>
T A<T>::getX() { return x; }

template<typename T>
B<T>::B(T x) : A{ x / 2 } {} // does not compile in gcc [1]

template<typename T>
C<T>::C(T x) : A<T>(x * 2) {} // compiles fine in both

template<typename T>
D<T>::D(T x) : A<T>{ x*x } {} // does not compile in MSVC 2015 [2]

/*
[1]: error: class 'B<T>' does not have any field named 'A'
     B<T>::B(T x) : A{ x / 2 } {}

[2]: error C2447: '{': missing function header (old-style formal list?)
*/

My online-search to figure out whether this is a compiler-bug or if it is invalid notation according to the standard remained fruitless. Can anybody please elucidate which notations used in B, C, and D are to be considered correct, please? Obviously both compilers agree on C, but naively I would consider the notations used in B and D valid as well.

Aucun commentaire:

Enregistrer un commentaire