n3797说:
§7.1.6.4/14:
使用占位符类型的返回类型声明的函数不应是虚拟的(10.3).
因此,以下程序格式错误:
struct s
{
virtual auto foo()
{
}
};
Run Code Online (Sandbox Code Playgroud)
虚拟
允许对虚函数进行返回类型推导是可能的,但这会使重写检查和vtable布局复杂化,因此似乎最好禁止这种情况.
任何人都可以提供进一步的理由或给出一个与上述引用一致的好(代码)示例吗?
感谢decltype
作为返回类型,C++ 11使得引入装饰器非常容易.例如,考虑这个类:
struct base
{
void fun(unsigned) {}
};
Run Code Online (Sandbox Code Playgroud)
我想用其他功能来装饰它,因为我会用不同种类的装饰做几次,所以我首先介绍一个decorator
简单地转发所有内容的课程base
.在真实的代码中,这是通过以下方式完成的,std::shared_ptr
这样我就可以删除装饰并恢复"裸"对象,并且所有内容都是模板化的.
#include <utility> // std::forward
struct decorator
{
base b;
template <typename... Args>
auto
fun(Args&&... args)
-> decltype(b.fun(std::forward<Args>(args)...))
{
return b.fun(std::forward<Args>(args)...);
}
};
Run Code Online (Sandbox Code Playgroud)
完美的转发,decltype
真是太棒了.在实际代码中,我实际上使用的是一个只需要函数名称的宏,其余的都是样板文件.
然后,我可以引入一个derived
为我的对象添加功能的类(derived
不正确,同意,但它有助于理解这derived
是一种base
,虽然不是通过继承).
struct foo_t {};
struct derived : decorator
{
using decorator::fun; // I want "native" fun, and decorated fun.
void fun(const foo_t&) {}
};
int main()
{
derived d; …
Run Code Online (Sandbox Code Playgroud) 我对以下代码感到困惑:
#include <iostream>
using namespace std;
int *foo()
{
//Operation
}
int main ()
{
auto int ret = foo();
}
Run Code Online (Sandbox Code Playgroud)
我在GCC下编译了上面的代码,但是我收到了以下错误:
error: two or more data types in declaration of 'ret'
auto int ret = foo();
Run Code Online (Sandbox Code Playgroud)
但是,如果我删除int
类型,如下:
auto ret = foo();
Run Code Online (Sandbox Code Playgroud)
然后它成功运行.
auto
是一个存储类,int
是一种数据类型,那么为什么我在第一种情况下得到"两种或更多数据类型"的错误?
我在GCC中编译了以下程序C++14
.
#include <iostream>
using namespace std;
auto func(int i);
int main()
{
auto ret = func(5);
return 0;
}
auto func(int i)
{
if (i == 1)
return i;
else
return func(i-1) + i;
}
Run Code Online (Sandbox Code Playgroud)
但是,我收到以下错误.
Run Code Online (Sandbox Code Playgroud)In function 'int main()': 8:16: error: use of 'auto func(int)' before deduction of 'auto' auto ret = func(5);
那么,我在这里错过了什么?
(这是“ “ decltype(auto)变量是否有实际用例? ”的后续文章)
考虑以下情况-我想将一个函数传递f
给另一个函数invoke_log_return
,该函数将:
调用f
;
打印一些东西到stdout ;
返回的结果f
,避免不必要的复制/移动并允许复制省略。
请注意,如果f
抛出异常,则不应将任何内容打印到stdout。这是我到目前为止的内容:
template <typename F>
decltype(auto) invoke_log_return(F&& f)
{
decltype(auto) result{std::forward<F>(f)()};
std::printf(" ...logging here...\n");
if constexpr(std::is_reference_v<decltype(result)>)
{
return decltype(result)(result);
}
else
{
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
让我们考虑各种可能性:
当f
返回prvalue时:
result
将成为一个对象;
invoke_log_return(f)
将是一个prvalue(有资格使用复制省略)。
当f
返回左值或x值:
result
将作为参考;
invoke_log_return(f)
将是一个左值或x 值。
您可以在godbolt.org上看到一个测试应用程序。如您所见, …
auto
C++ 11中的关键字可以替换函数模板和特化吗?如果是,使用模板函数和特化而不是简单地键入函数参数有什么好处auto
.如果没有,我完全期望被投入到地狱中,但我是C++的新手,但所以请放轻松我.
template <typename T>
void myFunction(T &arg)
{
// ~
}
Run Code Online (Sandbox Code Playgroud)
与
void myFunction(auto &arg)
{
// ~
}
Run Code Online (Sandbox Code Playgroud) gcc 4.9允许使用以下代码,但gcc 4.8和clang 3.5.0拒绝它.
void foo(auto c)
{
std::cout << c.c_str();
}
Run Code Online (Sandbox Code Playgroud)
我进入warning: ISO C++ forbids use of 'auto' in parameter declaration [-Wpedantic]
4.9但是在4.8和clang我得到error: parameter declared 'auto'
.
我想在编译期间检查类型是否是特定模板的实例化.
例如:
std::vector<int>
实例化 std::vector
std::array<int, 5>
实例化 std::array
我可以进行适用于案例1的测试,但不适用于案例2.
#include <iostream>
#include <type_traits>
#include <string>
#include <vector>
#include <array>
#include <queue>
template<template<typename...> class, typename...>
struct is_instantiation : public std::false_type {};
template<template<typename...> class U, typename... T>
struct is_instantiation<U, U<T...>> : public std::true_type {};
int main() {
using A = std::vector<int>;
std::cout << is_instantiation<std::vector, A>::value << "\n";
std::cout << is_instantiation<std::queue, A>::value << "\n";
// std::cout << is_instantiation<std::array, A>::value << "\n";
}
Run Code Online (Sandbox Code Playgroud)
如何让它适用于这两种情况?
我试过汽车,但无法使它工作.
相当简单的问题,
auto x11 {1,2,3,4};
auto x1 = {1,2,3,4};
auto x22 {1.0, 2.25, 3.5};
auto x2 = {1.0, 2.25, 3.5};
Run Code Online (Sandbox Code Playgroud)
据我了解,这里应该没有区别=
.但是,使用llvm/clang 6.0.0(使用--std = c ++ 17),我得到:
main1.cpp:35:17: error: initializer for variable 'x11' with type 'auto' contains multiple
expressions
auto x11 {1,2,3,4};
~~~~~~~~ ^
main1.cpp:37:20: error: initializer for variable 'x22' with type 'auto' contains multiple
expressions
auto x22 {1.0, 2.25, 3.5};
Run Code Online (Sandbox Code Playgroud)
从Stroustroup的C++书籍,第162页:
auto x1 {1,2,3,4}; // x1 is an initializer_list<int>
auto x2 {1.0, 2.25, 3.5 }; // x2 is an …
Run Code Online (Sandbox Code Playgroud) 假设我有foo
一个人口稠密的std::vector<double>
.
我需要对这个向量的元素进行操作.我有动力写作
for (auto it : foo){
/*ToDo - Operate on 'it'*/
}
Run Code Online (Sandbox Code Playgroud)
但似乎这不会回写,foo
因为它it
是一个值类型:已经采用了向量元素的深层副本.
我可以提供一些指导auto
来制作it
参考类型吗?然后我可以直接操作it
.
我怀疑我错过了一些简单的语法.