我依赖的是一个库,该库的作者广泛使用大括号表示法来调用所有构造函数,这是近年来许多团体热烈宣传和推荐的。
该库主要在使用gcc的Linux上开发,但旨在实现跨平台兼容,在我的情况下,该库在使用Visual Studio 2015的Windows上使用。
如果我尝试构建该库,则会收到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中使用的符号也有效。
答案 0 :(得分:0)
在符号B(如下)中,基类模板A
缺少模板参数(A
的构造函数引用了该参数),因此GCC(以及Clang)无法对其进行编译。
template<typename T>
B<T>::B(T x) : A{ x / 2 } {} // does not compile in gcc [1]
像这样进行更改。
template<typename T>
B<T>::B(T x) : A<T>{ x / 2 } {} // does not compile in gcc [1]
对于符号D,GCC(以及Clang也是如此)是正确的,因为存在用于A<int>
初始化的匹配构造函数。 MSVC拒绝它是错误的。