【发布时间】:2013-06-22 22:34:36
【问题描述】:
我正在尝试我的 C++11 代码,看看是否所有最近的主要编译器都支持我使用的功能,以及以下缩短的代码
#include <valarray>
struct T
{
double vv[3];
};
class V : public std::valarray<T>
{
public:
auto begin()->decltype(std::begin(static_cast<std::valarray<T>>(*this)))
{
return std::begin(static_cast<std::valarray<T>>(*this));
}
};
int main(void)
{
}
将使用 g++ 4.8.1(来自 Debian sid 存储库)、Intel C++ 编译器 13.1.1 20130313,但不能使用 Clang 3.3-2(来自 Debian sid 存储库)进行编译。
给定的错误是:
test.cpp:11:73: error: no viable conversion from 'V' to 'std::valarray<T>'
auto begin()->decltype(std::begin(static_cast<std::valarray<T>>(*this)))
^~~~~
然而,像这样的代码
namespace std
{
auto begin(V& vv) -> decltype(std::begin(static_cast<V::parent_t>(vv)))
{
return std::begin(static_cast<V::parent_t>(vv));
}
}
将由所有三个编译器编译。
我的问题是:代码本身是语言标准允许的,只是 Clang 错误编译了它,还是只被 g++/icc 扩展支持?还是未定义的行为?
【问题讨论】:
-
我认为(但不确定)V 在其成员的声明符(包括尾随返回类型)中不完整,因此不允许对其基类进行 static_cast,因为它需要一个完整的类型。我更确定它不完整的事实然后关于这不允许演员表。
-
你可以试试
*static_cast<std::valarray<T>*>(this) -
或者直接使用
decltype(begin(valarray<T>())) -
这并不能回答您的问题,但clang 似乎更喜欢
*static_cast<std::valarray<T>*>(nullptr)的更常见使用模式 -
我不明白为什么它需要一个完整的类型。可以将不完整的类型传递给引用参数(复制或移动构造函数)。
标签: c++11 g++ clang static-cast