我有下面的代码,为什么visitor1
和visitor2
给出错误?
这是否意味着访问者无法在变体中返回一种类型?
#include <iostream>
#include <variant>
struct Visitor1
{
template <class T>
T operator()(const T & t) const
{
return (t);
}
};
struct Visitor2
{
int operator()(const int & t) const
{
return std::get<int>(t);
}
char operator()(const char & t) const
{
return std::get<char>(t);
}
};
struct Visitor3
{
void operator()(const int & t) const
{
std::cout<<t;
}
void operator()(const char & t) const
{
std::cout<<t;
}
};
int main()
{
std::variant<int, char> v{char(100)};
std::visit(Visitor3{}, v);
auto t = std::visit(Visitor2{}, v); //fails
//auto t = std::visit(Visitor1{}, v); //fails
std::cout << t;
}
我知道我可以使用std::get()
,但是问题是我只能将auto
与std::get()
一起使用,如果我执行以下操作,则无法访问x
在if / else范围之外:
bool b;
Variant v;
if (b)
{
auto x = std::get<int>(v);
}
else
{
auto x = std::get<char>(v);
}
// I want to do something with x here out of if/else
答案 0 :(得分:2)
我有下面的代码,为什么visitor1和visitor2给出错误?
因为C ++是一种强类型语言。
写作时
auto t = std::visit(Visitor2{}, v); //fails
编译器必须决定编译类型为t
的编译时间,因此必须决定哪种类型返回std::visit(Visitor2{}, v)
。
如果Visitor2
返回char
,则当v
包含char
时,或者返回int
,当v
包含{{1 }},编译器无法选择(编译时!)从int
返回的类型[也存在std::visit()
中的Visitor2
的问题(仅t
) }是operator()
或int
,因此无法对其应用char
。
与std::get()
相同的问题:模板Visitor1
返回模板类型,因此operator()
的{{1}}或int
。
char
之所以有效,是因为两个std::variant<int, char>
都返回Visitor3
,因此编译器可以解析(编译时)operator()
返回(在某种意义上)void
也许在this page中有更好的解释:
[{
std::visit(Visitor3{}, v)
]有效地返回void
,其中
std::visit()
是std::invoke(std::forward<Visitor>(vis), std::get<is>(std::forward<Variants>(vars))...)
。从返回的表达式推论出返回类型,就像is...
一样。对于所有变体的替代类型的所有组合,如果上述调用不是同一类型和值类别的有效表达式,则调用格式错误。
答案 1 :(得分:2)
一种语言可能具有C ++的许多功能,可以满足您的需求。
为了做您想做的事,当您调用std::visit
时,必须编写该函数其余部分的N种不同实现。
在这N种不同的实现方式(您的情况是2种)的每一种中,变量的类型都会不同。
C ++不能那样工作。
唯一与访问调用“相乘”的部分是访问者。
int main()
{
std::variant<int, char> v{char(100)};
std::visit([&](auto && t){
std::cout << t;
}, v);
}
我将函数的其余部分放置在访问者中。对于访问者中可以存储的每种类型,该代码都会实例化一次。
返回的所有内容都可以返回到调用范围的“单个实例”正文。
基本上,[&](auto&& t)
lambda可以执行您想要的操作。
现在,我们可以做一些技巧来稍微更改语法。
我的最爱是:
v->*visit*[&](auto&& val) {
std::cout << val;
return [val](auto&& x) { x << val; };
}->*visit*[&](auto&& outputter) {
outputer(std::cout);
};
其中->*visit*
使用相对荒谬的元编程来允许
导致访问的指定运营商
将访问的返回值融合到一个变体中。
但没有理智的人会编写该代码。
答案 2 :(得分:1)
你可以
import { Pipe, PipeTransform } from "@angular/core";
import { Opportunity } from "../models/Opportunity";
@Pipe({
name: "orderBy",
pure: false
})
export class OrderByPipe implements PipeTransform {
/**
* Method to sort data and return sorted data
*
* @param records
* @param args
*/
transform(records: Array<any>, args?: any): any {
return records.sort(function (a, b) {
if (a[args.property] < b[args.property]) {
return -1 * args.order;
}
else if (a[args.property] > b[args.property]) {
return 1 * args.order;
}
else {
return 0;
}
});
}
}