我惊讶地发现,当使用尾随返回类型而不是正常返回类型时,GCC允许函数返回数组.你可能知道数组不能被复制所以这是非常有限的,但让我向你展示一些很酷的例子.
#include <iostream>
#include <typeinfo>
using namespace std;
auto func() -> int [5]
{
return {4, 56, 78, 4, 0};
}
int main()
{
cout << func()[2] << endl;
cout << typeid(func).name() << endl;
}
Run Code Online (Sandbox Code Playgroud)
这是编译器错误还是一些新功能?
有趣的是'typeid'返回'FA5_ivE',它被解析为' int (()) [5]',这意味着你认为函数返回5个int的数组.
编辑:我尝试将返回的数组绑定到右值引用但没有任何成功(使用大多数可能的形式):
auto &&refArrayTemp{ func() };
Run Code Online (Sandbox Code Playgroud)
似乎这种扩展是无用的.
我不明白为什么?我不认为兼容性应该是一个问题,因为没有说明符声明的函数实际上将它隐式定义为false.如果它是关于名称修改 - 我们可以假设旧的(现有的)将暗示noexcept(false)并且为noexcept(true)添加另一个新符号.
这在使用模板时会很有用,因为现在比较函数类型和noexcept说明符应该分开进行.我基本上的意思是:
int func() noexcept(true), func_1() noexcept(false);
decltype(func) == decltype(func_1); //this now equals true
Run Code Online (Sandbox Code Playgroud)
但另一方面,如果我们通过使用指针或引用进行函数赋值,则检查noexcept说明符,就好像它是类型的一部分:
int (&refFunc)() noexcept(true) = func_1; //target exception specification is not superset of source
int (&refFunc)() noexcept(true) = func; //ok
Run Code Online (Sandbox Code Playgroud)
所以现在实现全功能匹配应该通过执行类型和noexcept检查来完成,这有点复杂:
decltype(func) == decltype(func_1) && noexcept(func()) == noexcept(func_1()); //this now equals false
Run Code Online (Sandbox Code Playgroud)
想象一下,如果函数有参数:
int func(int, double) noexcept(true), func_1(int, double) noexcept(false);
decltype(func) == decltype(func_1) && noexcept(func(int{}, double{})) == noexcept(func_1(int{}, double{})); //this now equals false
Run Code Online (Sandbox Code Playgroud) 这是允许的:
int a[]{1, 2, 3};
Run Code Online (Sandbox Code Playgroud)
但不是这个:
auto a = new int[]{1, 2, 3};
Run Code Online (Sandbox Code Playgroud)
您必须指定边界.为什么?
编辑:正确的语法(不编译)是:
auto a = new (int[]){1, 2, 3};
Run Code Online (Sandbox Code Playgroud)
这给出了真正的错误消息,即:
error: invalid use of array with unspecified bounds
Run Code Online (Sandbox Code Playgroud) 我在我的Windows系统上安装了http://sourceforge.net/projects/clangonwin/.我的问题是:
我真的找不到任何用途.我的第一个想法是,我可以使用它来实现'按合同设计',而不使用像这样的宏:
struct S
{
S(constexpr int i) : S(i) { static_assert( i < 9, "i must be < 9" ); }
S(int i); //external defintion
char *pSomeMemory;
};
Run Code Online (Sandbox Code Playgroud)
但这不会编译.我想我们也可以使用它来引用同一变量,而不需要创建额外的内存,当我们想要避免get/setters时,为了使用户的一个成员的实例是只读的:
class S
{
private:
int _i;
public:
const int & constexpr i = _i;
};
Run Code Online (Sandbox Code Playgroud)
但以上都没有实际编译过.有人可以告诉我为什么要引入这个关键字?
如何通过最少的修改来定义线程安全的全局数组?
我希望通过使用互斥锁和同步块来完成对它的每次访问.
像"T"这样的东西会是某种类型(请注意'sync'关键字当前未定义为AFAIK):
sync Array!(T) syncvar;
Run Code Online (Sandbox Code Playgroud)
每次访问它都将与此类似:
Mutex __syncvar_mutex;
//some func scope....
synchronized(__syncvar_mutex) { /* edits 'syncvar' safely */ }
Run Code Online (Sandbox Code Playgroud) 有这样的事情,它在最新的C++草案中:
在第7.1.2 .4节:
内联函数应在每个使用过的翻译单元中定义,并且在每种情况下都应具有完全相同的定义(3.2).[注意:在定义出现在翻译单元之前,可能会遇到对内联函数的调用. - 结束注释]如果函数的定义在第一次声明为内联之前出现在翻译单元中,则程序格式不正确.如果在一个翻译单元中内联声明具有外部链接的功能,则应在其出现的所有翻译单元中内联声明; 无需诊断.具有外部链接的内联函数在所有翻译单元中应具有相同的地址.外部内联函数中的静态局部变量始终引用同一个对象.在extern内联函数体内定义的类型在每个翻译单元中都是相同的类型.
关于什么是什么以及何时使用它的一些见解?
我有以下WinRT代码,可以很好地发现活动的VPN配置文件:
VpnManagementAgent vpn;
auto profiles = vpn.GetProfilesAsync().get();
wprintf(L"Found %d profiles\n", profiles.Size());
for (auto vp : profiles)
{
wprintf(L"Found profile %s\n", vp.ProfileName().c_str());
}
Run Code Online (Sandbox Code Playgroud)
我想检查ConnectionStatus,但这在IVpnProfile接口上不可用。我尝试添加以下内容无济于事,因为具体的VpnPlugInProfile和VpnNativeProfile类中的ConnectionStatus可用:
VpnPlugInProfile pp = vp.as<VpnPlugInProfile>();
if (pp != nullptr)
wprintf(L"ConnectionStatus = %d\n", pp.ConnectionStatus());
Run Code Online (Sandbox Code Playgroud)
这只是给出一个无效的句柄错误。
有没有办法从IVpnProfile获取ConnectionStatus?
例如,如果我们有一个std::array并且我们使用constexpr编译器实例化一个超出绑定的元素将不会报告错误:
constexpr int EvaluateSpecialArrayIndex(int a)
{ return a * sizeof(int); }
array<int, 5> arr;
cout << arr[98] << endl; //compiles fine
cout << arr[EvaluateSpecialArrayIndex(4)] << endl; //the same as above
Run Code Online (Sandbox Code Playgroud)
我们不能以某种方式限制这个吗?
想象一下我写这个奇怪的原因:
int main()
{
struct S
{
int i;
} var;
int decltype(var)::* pint = &decltype(var)::i;
}
Run Code Online (Sandbox Code Playgroud)
GCC似乎编译得很好,尽管Clang失败了一些不确定的语法相关错误消息.
那么神圣的ISO论文对此有何评论 - 这是否有效?