声明的允许使用上下文
Permitted usage context of declarations
如下代码
#include <iostream>
#include <memory>
#include <ios>
using std::cout;
using std::endl;
using std::unique_ptr;
using std::make_unique;
using std::boolalpha;
template<typename T>
struct alloc{
alloc();
unique_ptr<T> operator() (void){
return(auto up = make_unique<T>(NULL));
}
};
int main (void){
auto up = alloc<int>()();
cout << boolalpha << ((up) ? 1 : 0) << endl;
return 0;
}
编译时出现如下错误:
g++ -ggdb -std=c++17 -Wall -Werror=pedantic -Wextra -c code.cpp
code.cpp: In member function ‘std::unique_ptr<_Tp> alloc<T>::operator()()’:
code.cpp:14:16: error: expected primary-expression before ‘auto’
return(auto up = make_unique<T>(NULL));
^~~~
code.cpp:14:16: error: expected ‘)’ before ‘auto’
make: *** [makefile:20: code.o] Error 1
早前有一个关于SO的问题报同样的错误:
以下是上述问题的已接受答案的摘录:
Declarations are not expressions. There are places where expressions
are allowed, but declararions are not.
所以我根据得到的编译错误提出的问题是:
a) 标准不允许在 return 语句中使用声明吗?
b) 允许的声明上下文是什么?
注意:我故意在 return 语句中使用 auto 关键字来重现此错误。此错误最初出现在较大的代码库中。
TIA
Is the use of a declaration in a return statement not permitted by the standard?
确实不是。我们只需要检查 [stmt.jump]/1
处的语法产生式
Jump statements unconditionally transfer control.
jump-statement:
break ;
continue ;
return expr-or-braced-init-listopt ;
goto identifier ;
没有将 "expr-or-braced-init-list" 转换为任何类型语句的产生式,因此也没有声明语句。也没有产生式将其转换为任何其他类型的声明(例如函数、名称空间或 class)。所以你不能在 return 语句的操作数中声明任何东西。
What are the permitted contexts for declarations?
几乎所有不需要显式表达式的地方。 C++ 中翻译单元的定义(一个正在翻译的文件)是每个 [basic.link]/1.
的一系列声明
A program consists of one or more translation units linked together. A
translation unit consists of a sequence of declarations.
translation-unit:
declaration-seqopt
不同的声明有不同的结构。诸如名称空间之类的一些可能包含更多声明。其他如函数可能包含语句,这些语句本身可能是某些事物的声明语句。但最重要的是,该标准明确了语句可以出现的位置,以及只允许使用表达式的位置。
如下代码
#include <iostream>
#include <memory>
#include <ios>
using std::cout;
using std::endl;
using std::unique_ptr;
using std::make_unique;
using std::boolalpha;
template<typename T>
struct alloc{
alloc();
unique_ptr<T> operator() (void){
return(auto up = make_unique<T>(NULL));
}
};
int main (void){
auto up = alloc<int>()();
cout << boolalpha << ((up) ? 1 : 0) << endl;
return 0;
}
编译时出现如下错误:
g++ -ggdb -std=c++17 -Wall -Werror=pedantic -Wextra -c code.cpp
code.cpp: In member function ‘std::unique_ptr<_Tp> alloc<T>::operator()()’:
code.cpp:14:16: error: expected primary-expression before ‘auto’
return(auto up = make_unique<T>(NULL));
^~~~
code.cpp:14:16: error: expected ‘)’ before ‘auto’
make: *** [makefile:20: code.o] Error 1
早前有一个关于SO的问题报同样的错误:
以下是上述问题的已接受答案的摘录:
Declarations are not expressions. There are places where expressions are allowed, but declararions are not.
所以我根据得到的编译错误提出的问题是:
a) 标准不允许在 return 语句中使用声明吗?
b) 允许的声明上下文是什么?
注意:我故意在 return 语句中使用 auto 关键字来重现此错误。此错误最初出现在较大的代码库中。
TIA
Is the use of a declaration in a return statement not permitted by the standard?
确实不是。我们只需要检查 [stmt.jump]/1
处的语法产生式Jump statements unconditionally transfer control.
jump-statement: break ; continue ; return expr-or-braced-init-listopt ; goto identifier ;
没有将 "expr-or-braced-init-list" 转换为任何类型语句的产生式,因此也没有声明语句。也没有产生式将其转换为任何其他类型的声明(例如函数、名称空间或 class)。所以你不能在 return 语句的操作数中声明任何东西。
What are the permitted contexts for declarations?
几乎所有不需要显式表达式的地方。 C++ 中翻译单元的定义(一个正在翻译的文件)是每个 [basic.link]/1.
的一系列声明A program consists of one or more translation units linked together. A translation unit consists of a sequence of declarations.
translation-unit: declaration-seqopt
不同的声明有不同的结构。诸如名称空间之类的一些可能包含更多声明。其他如函数可能包含语句,这些语句本身可能是某些事物的声明语句。但最重要的是,该标准明确了语句可以出现的位置,以及只允许使用表达式的位置。