我想计算函数组合 - f ( g (param) )。这是我尝试过的:
auto fComposition(auto&& f, auto&& g, auto&&... params)
{
/* some stuff */
auto result = std::forward<decltype(f)>(f)(
std::forward<decltype(g)>(g)(
std::forward<decltype(params)>(param)
)
);
/* other stuff */
return result;
};
Run Code Online (Sandbox Code Playgroud)
编译用
g++ -std=c++17 src.cpp
Run Code Online (Sandbox Code Playgroud)
基本测试
#include <random>
#include <math.h>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<double> distr(-1.0, 1.0);
auto xx = fComposition(round, distr, gen);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我收到消息说它无法识别第一个函数的类型。
我正在为我的一些类编写一个身份函数,用于记录其调用次数(长话短说:指标)。
目前,我正在尝试计算使用模板与使用auto
.
这是从我正在做的代码中摘取的一个简短示例:
namespace Metrics {
unsigned long identifications = 0;
//auto version
auto identity(auto i) {
//... other stuffs
identifications++;
return i;
};
//template version
template<class I> I identity(I i) {
//... other stuffs
identifications++;
return i;
};
};
Run Code Online (Sandbox Code Playgroud)
还有更多事情要做,但这是基础知识。我知道编译器只会为每个函数创建一个函数,即
identity(5);
identity("5");
//generates the functions
int identity(int i) { ... return i; };
const char* identity(const char* i) { ... return i; };
Run Code Online (Sandbox Code Playgroud)
在运行时,哪个更快?他们有编译时间差异吗?
由于这个函数需要被多次调用,所以我对运行时性能更感兴趣,但是也可能有大量类型可以为其生成函数,所以我也对哪个类型更快感兴趣在编译时。
当函数调用多个类型参数时,如何替换函数参数中的 auto 关键字?因为我想使用-std=c++11
并且在 omnet++ 中收到此错误:
**error: use of auto in parameter declaration only available with -std=c++14 or -std=gnu++14**
Run Code Online (Sandbox Code Playgroud)
void get_index(auto s_arra[], auto elem) {
...
}
void main() {
get_index(float array1, float var1);
get_index(int array2, int var2);
}
Run Code Online (Sandbox Code Playgroud) 全部。非常快的问题。为什么像下面这样的语句可以使用最新的 gcc 或 MSVC 进行编译,但使用自定义类型却无法进行相同的操作?
\nconst auto& a = isParamFP16 ? 0 : "aaa";
- 可能\n const auto& a = isParamFP16 ? paramFP32 : paramFP16;
- 不可能(error C2446: ':': no co nversion from 'const T' to 'const T'
对于 MSVC 和operands to ?: have different types \xe2\x80\x98const param<FP32>\xe2\x80\x99 and \xe2\x80\x98const param<FP16>\xe2\x80\x99
gcc)
我知道所有类型都应该在编译时解析,但为什么第一个变体有效?
\n谢谢。
\n我们如何创建一个可以为 auto 变量分配不同类型的 C++ 函数?
\nnlohmann json 包执行此操作,这证明它\xe2\x80\x99s 是可能的:
\n#include <iostream>\n#include "./x64/Debug/single_include/nlohmann/json.hpp"\nusing namespace std;\n\nusing json = nlohmann::json;\n\nint main()\n{\n nlohmann::json obj = nlohmann::json::parse("{ \\"one\\": \\"111\\", \\"two\\": 222}");\n\n string res1 = obj["one"]; // Types defined:\n int res2 = obj["two"];\n\n auto a1 = obj["one"]; // Auto variables:\n auto a2 = obj["two"];\n\n cout << "Types defined: " << res1 << ' ' << res2 << endl;\n cout << "Auto variables: " << a1 << ' ' << a2 << endl;\n}\n
Run Code Online (Sandbox Code Playgroud)\n结果: …
再次:
std::vector<std::string> someFunction() {
auto vec;
return vec;
}
Run Code Online (Sandbox Code Playgroud)
vec
是什么阻止“auto”推断as的类型std::vector<std::string>
?
有时,在您不想显式指定类型的情况下创建正确类型的变量非常有用,特别是当类型是复杂类型(例如std::map<std::string, std::tuple<int, SomeStructure>>
(1)时) 。这是几乎总是自动指南的核心。
对于初始化变量的情况,可以使用:
\nauto a = 3.14159f; // float.\nauto a = function_returning_type(1, 2, 3); // whatever that function returns.\n
Run Code Online (Sandbox Code Playgroud)\n如果你不想初始化它,你可以使用decltype
它来定义它:
int a;\ndecltype(a) b; // integer\n\n\nfloat c();\ndecltype(c()) d; // float\n
Run Code Online (Sandbox Code Playgroud)\n如果您想将类型基于某个函数返回的内容而不是现有的变量,那么最后一个特别方便。但是,如果该函数的唯一重载需要很多参数,则似乎需要您提供它们:
\nint a(const char *, int, float);\ndecltype(a("", 7, 4.2)) b; // okay\ndecltype(a()) c; // not okay\n
Run Code Online (Sandbox Code Playgroud)\n第二个样本给出了类似的内容:
\nerror: too few arguments to function \xe2\x80\x98int a(const char *, int, float)\xe2\x80\x99\n decltype(a()) c;\n ^\n
Run Code Online (Sandbox Code Playgroud)\n尽管事实上在这种情况下不需要参数, …
考虑这个结构。它是一个范围,但使用模板而不是构造函数,使值静态:
template <int min_v, int max_v>
struct num_range final {
constexpr static int min = min_v;
constexpr static int max = max_v;
}
// now you can do
std::cout << num_range<1,3>::min << '\n'; // prints 1
Run Code Online (Sandbox Code Playgroud)
但这是固定的int
。如果我希望 C++ 从第一个参数推导数字类型并将其强制应用于第二个参数,该怎么办?
我试过这个:
template <typename TNumber>
template <TNumber min_v, TNumber max_v>
struct num_range final
Run Code Online (Sandbox Code Playgroud)
我按照相反的顺序尝试了。我知道你可以这样做:
template <auto min_v, decltype(min_v) max_v>
struct num_range final {
using num_type = decltype(min_v);
constexpr static num_type min = min_v;
constexpr static num_type max = max_v;
}; …
Run Code Online (Sandbox Code Playgroud) 在第3章:C++之旅:抽象机制的第82页中,作者写道:
如果我们还想为Vector使用range-for循环,我们必须定义合适的begin()和end()函数:
template<typename T>
T? begin(Vector<T>& x)
{
return &x[0]; // pointer to ?rst element
}
template<typename T>
T? end(Vector<T>& x)
{
return x.begin()+x.size(); // pointer to one-past-last element
}
Run Code Online (Sandbox Code Playgroud)
鉴于这些,我们可以写:
void f2(const Vector<string>& vs) // Vector of some strings
{
for (auto s : vs)
cout << s << ’\n’;
}
Run Code Online (Sandbox Code Playgroud)
请注意,类模板Vector在草稿的第81页中定义.
基本上,这是我的代码的样子:
vector<int> myVec; // defined elsewhere, and has stuff in it.
auto it = lower_bound(myVec.front(), myVec.back(), key);
myVec.insert(it, key); // <- compiler error!
Run Code Online (Sandbox Code Playgroud)
编译器错误error: no matching function for call to 'std::vector<int>::insert(int&, int&)'
,这是意外的,因为它应该是一个" something_something_iterator
".
为什么这样做?
我在Windows 7上使用MinGW-W64进行编译.