C++中的括号用于许多地方:例如,在函数调用和分组表达式中,以覆盖运算符优先级.除了非法的额外括号(例如函数调用参数列表周围)之外,C++的一般但非绝对规则是额外的括号永远不会受到伤害:
5.1主要表达式[expr.prim]
5.1.1一般[expr.prim.general]
6带括号的表达式是一个主表达式,其类型和值与所附表达式的类型和值相同.括号的存在不会影响表达式是否为左值.除非另有说明,否则带括号的表达式可以在与可以使用所包含的表达式的上下文完全相同的上下文中使用,并且具有相同的含义.
问题:在哪些上下文中,额外的括号会改变C++程序的含义,而不是覆盖基本的运算符优先级?
注意:我认为没有括号的指针到成员语法的限制&qualified-id超出了范围,因为它限制了语法而不是允许两个具有不同含义的语法.同样,在预处理程序宏定义中使用括号也可以防止不必要的运算符优先级.
从我的个人经验以及从咨询答案到诸如decltype(auto)有什么用途的问题?我可以找到许多有价值的用例decltype(auto)作为函数返回类型占位符。
但是,我在努力思考decltype(auto)变量的任何有效(即有用,现实,有价值)用例时都非常费劲。我想到的唯一可能性是存储函数返回的结果以decltype(auto)供以后传播,但auto&&也可以在此使用,这样会更简单。
我什至搜索了我所有的项目和实验,其中391个出现的decltype(auto)都是返回类型的占位符。
那么,变量是否有实际的用例decltype(auto)?还是仅当用作返回类型占位符时此功能才有用?
您如何定义“现实”?
我正在寻找一个能提供价值的用例(即,不仅仅是显示功能如何工作的示例)decltype(auto),与诸如auto&&或根本不声明变量的替代方案相比,哪里是最佳选择。
问题域无关紧要,它可能是一些晦涩的元编程极端案例或神秘的功能编程构造。但是,该示例需要使我接受“嘿,这很聪明/很漂亮!” 而使用任何其他功能来达到相同的效果将需要更多样板,或者存在某种缺陷。
我在显式和自动尾随返回类型之间发现了一个奇怪的区别.
在下面的代码中,我们定义了一个在整数和iter函数上模板化的结构,它将这种类型的一个对象作为参数.返回类型取决于在递减模板值后调用自身的结果.
为了打破实例化循环(或者我认为),我提供了一个返回非依赖类型的特化.
我们有一个玩具主体来实例化模板.
这是一些代码:
template<int i> struct Int {};
constexpr auto iter(Int<0>) -> Int<0>;
template<int i> constexpr auto iter(Int<i>) -> decltype(iter(Int<i-1>{}));
int main(){
decltype(iter(Int<10>{})) a;
}
Run Code Online (Sandbox Code Playgroud)
此代码在gcc 4.9和clang 3.5中都不起作用.两者都触发无限实例化(它们与专用基本情况不匹配).
rec.cpp:11:62: fatal error: recursive template instantiation exceeded maximum depth of 256
template<int i> constexpr auto iter(Int<i>) -> decltype(iter(Int<i-1>{}));
Run Code Online (Sandbox Code Playgroud)
现在,如果我们使用C++ 14 decltype(auto)并且我们为模板提供了一个返回完全相同的东西:
template<int i> struct Int {};
constexpr auto iter(Int<0>) -> Int<0>;
template<int i>
constexpr auto iter(Int<i>) -> decltype(auto) {
return iter(Int<i-1>{});
}
int main(){
decltype(iter(Int<10>{})) a;
}
Run Code Online (Sandbox Code Playgroud)
这现在适用于两个编译器并按预期运行.
我尝试了不同的方式来表达专业化并稍微移动一下(要小心它的位置),但这并没有阻止它的自焚;( …
我有两个变量,我想分别处理较大和较小的一个。
我的方法:
a = 1;
b = 2;
if (a >= b){
int c = a;
int d = b;
}
else{
int c = b;
int d = a;
}
Run Code Online (Sandbox Code Playgroud)
我获得的未使用的变量的错误,当我尝试使用c和d以后,它说
c无法解决
有办法解决吗?
我遇到了这段包含尾随返回类型和继承的代码片段。
以下最小示例可以使用g ++而不是clang进行编译
struct Base {};
int foo(Base&) {
return 42;
}
struct Derived : public Base {
auto bar() -> decltype(foo(*this)) {
return foo(*this);
}
};
int main()
{
Derived derived;
derived.bar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我们更改auto bar() -> decltype(foo(*this))为decltype(auto) bar()(c ++ 14扩展名),代码也会使用clang进行编译。链接到Godbolt https://godbolt.org/z/qf_k6X。
谁能解释我
auto bar() -> decltype(return expression)不同decltype(auto) bar()请考虑C++模板中的引用:完整指南(第2版):
Run Code Online (Sandbox Code Playgroud)decltype(auto) ret{std::invoke(std::forward<Callable>(op), std::forward<Args>(args)...)}; ... return ret;需要注意的是,宣布
ret与auto&&不正确.作为引用,auto&&将返回值的生存期延长到其作用域的末尾,但不超出return对函数调用者的语句.
作者说这auto&&不适合完美转发回报值.但是,是否也没有decltype(auto)形成对xvalue/lvalue的引用?国际海事组织,decltype(auto)然后遭受同样的问题.那么,作者有什么意义呢?
编辑:
上面的代码片段应该放在这个函数模板中.
template<typename Callable, typename... Args>
decltype(auto) call(Callable&& op, Args&&... args) {
// here
}
Run Code Online (Sandbox Code Playgroud) 我想要做的是定义如下3个函数:
template<int t = 0> int test() { return 8; }
template<int t = 1> float test() { return 8.8; }
template<int t = 2> std::string test() { return "8.9"; }
int main()
{
int a = test<0>();
float b = test<1>();
std::string c = test<2>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它们使用相同类型的模板参数,但返回不同类型。
我相信一定有某种方法可以做到这一点(就像这样 std::get<>()做),但是我找不到如何做到这一点。
template<typename T>
concept Octet = 1 == sizeof(T);
// ok
Octet decltype(auto) c = 'a';
// ok
void f1(const auto&) {}
// ok
void f2(Octet auto) {}
// ok
void f3(Octet auto&&) {}
// error: expected ‘auto’ or ‘decltype(auto)’ after ‘Octet’
void f4(Octet const auto&) {}
// error: cannot declare a parameter with ‘decltype(auto)’
void f5(Octet decltype(auto)) {}
Run Code Online (Sandbox Code Playgroud)
与gcc-11 -std=c++20. 请参阅:https : //godbolt.org/z/xK769Pfjn
为什么 f4 和 f5 不工作?
当使用auto&&处理函数返回一个左值:
int func()
{
int v=42;
return v;
}
auto && v = func();
Run Code Online (Sandbox Code Playgroud)
将其v视为左值而不是左值的后果是什么?这些后果是否证明使用decltype(auto)代替auto&&对函数的返回类型执行通用处理是合理的?
请考虑以下代码:
template< class T1 , class T2>
auto calc( T1 a , T2 b )
{
return a + b ;
}
template< class T1 , class T2>
auto calc( T1 a , T2 b ) -> decltype( a + b )
{
return a + b ;
}
Run Code Online (Sandbox Code Playgroud)
什么是第二个代码的差异?你能举一些例子说明这会产生什么影响,还是会有所不同?
c++ ×10
c++11 ×3
c++14 ×3
templates ×3
auto ×2
decltype ×2
c++-concepts ×1
c++-faq ×1
c++20 ×1
inheritance ×1
parentheses ×1
return-type ×1