Я зависел от библиотеки, авторы которой широко использовали скобки для вызова всех конструкторов, как это любезно рекламировалось и рекомендовалось рядом сторон в последние годы.
Библиотекав основном разрабатывается на Linux с использованием gcc, но стремится к кросс-платформенной совместимости и в моем случае используется на Windows с использованием Visual Studio 2015.
Если я пытаюсь собрать библиотеку, я получаю ошибку компилятора C2447, которая возникает, когдашаблоны шаблонов используют эту фигурную скобку.Я попытался проиллюстрировать мой случай следующим 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?)
*/
Мой онлайн-поиск, чтобы выяснить, является ли это ошибкой компилятора или это неверная запись в соответствии со стандартом, осталась бесплодной.Кто-нибудь может объяснить, какие обозначения, используемые в B, C и D, следует считать правильными?Очевидно, что оба компилятора согласны с C, но наивно я считаю, что обозначения, используемые в B и D, также верны.