- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我想知道如何 std::visit
返回类型转换应该有效。
上下文如下:我有一个变体对象,我想根据其基础类型应用(通过 std::visit
)不同的函数。每个函数的结果可能有不同的类型,但我希望 std::visit 将它打包成一个变体类型。
伪代码:
我有:
variant<A,B> obj
f(A) -> A
f(B) -> B
我要:
if obj is of type A => apply f(A) => resA of type A => pack it in variant<A,B>
if obj is of type B => apply f(B) => resB of type B => pack it in variant<A,B>
现在,根据cppreference ,std::visit 的返回类型是“访问者的选定调用返回的值,转换为所有可能的 std::invoke 表达式的通用类型”但是没有指定普通类型的含义。是std::common_type
?在这种情况下,它不适用于 gcc 7.2:
#include <variant>
#include <iostream>
#include <type_traits>
struct A {
int i;
};
struct B {
int j;
};
// the standard allows to specialize std::common_type
namespace std {
template<>
struct common_type<A,B> {
using type = std::variant<A,B>;
};
template<>
struct common_type<B,A> {
using type = std::variant<A,B>;
};
}
struct Functor {
auto
operator()(A a) -> A {
return {2*a.i};
}
auto
operator()(B b) -> B {
return {3*b.j};
}
};
int main() {
std::variant<A,B> var = A{42};
auto res = std::visit( Functor() , var ); // error: invalid conversion from 'std::__success_type<B>::type (*)(Functor&&, std::variant<A, B>&) {aka B (*)(Functor&&, std::variant<A, B>&)}' to 'A (*)(Functor&&, std::variant<A, B>&)' [-fpermissive]
}
我应该如何表达这种解包-申请访问-重新打包模式?
注意事项:
1) 专攻 std::common_type<A(*)(Ts...),B(*)(Ts...)>
不会削减它。这可以解决问题,但依赖于特定的 std::lib 实现细节。 此外,它不适用于多次访问。
2)我给出的例子真的是精简到最低限度,但是你要想象我要提供的访问机制是在图书馆端,而访问者是在客户端,可以任意复杂:未知数量和类型的参数,未知返回类型。图书馆应该只提供访问和一组预定义的 std::common_type
用于访问返回类型的特化。例如,定义
auto f = [](auto x) -> variant<A,B> { return Functor()(x); };
然后申请std::visit
至 f
不是一个可行的选择:从图书馆的角度来看,我无法在不知道“打包”返回类型的情况下预定义这种 lambda。 [主要问题是我没有办法询问 std::common_type
的语言。一个特定的重载集]
最佳答案
您可以创建自己的 visit
层,例如:
template <typename Visitor, typename ... Ts>
decltype(auto) my_visit(Visitor&& vis, const std::variant<Ts...>& var)
{
return std::visit([&](auto&& e)
-> std::common_type_t<decltype(vis(std::declval<Ts>()))...>
{
return vis(e);
}, var);
}
关于c++ - 变体访问和 common_type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46103745/
我想知道如何 std::visit返回类型转换应该有效。 上下文如下:我有一个变体对象,我想根据其基础类型应用(通过 std::visit )不同的函数。每个函数的结果可能有不同的类型,但我希望 st
在 Nicolai M. Josuttis 的“The Cpp standard library”一书中,第 2 版中说(5.4,p.125)struct common 类型的定义如下: templa
为了了解它是如何工作的,我查看了标题 type_traits 中 std::common_type 的 libstdc++ 实现。我不得不承认我并不真正理解它是如何工作的。在这里: /// commo
模板类std::common_type将通用类型计算为可变参数类型列表。 It is defined using the return type of the ternary operator x:y
我开始查看 std::common_type并且不确定它的用途和功能。有几件事让我觉得很奇怪: 参数的顺序很重要:common_type可能与 common_type 不同.一个可能编译,另一个可能不
我不确定如何描述模板的类型何时是结构本身,如下所示。 template struct Point{}; Point> p; 这是定义的行为吗?如果是这样,我不知道实现它的最佳方法,以便我可以返回一个没
我想编写一个辅助模板来检查模板参数包是否具有通用类型,即,是否将 std::common_type 应用于包定义了一个类型。 使用 std::void_t在 SFINAE 中,我得出了以下定义: te
自 C++11 以来,引入了类型特征 std::common_type。 std::common_type 确定其所有模板参数之间的公共(public)类型。在 C++14 中,还引入了辅助类型 st
我注意到 std::chrono::duration的一元 + 和 - 运算符在 libcxx 中实现返回类型为 typename common_type::type .为什么不是简单的duratio
以下是 std::common_type 的专业之一. template struct common_type { typedef decltype(true ? declval() : d
此代码在 VC11 下为两个检查打印出“unsigned short”,但在 VC10 下第一个检查打印“int”。我总是期待 std::common_type::type成为T .这是错误还是允许的
我很困惑:升级到 GCC 6 (RC1) 后,一些使用 std::common_type 的模板代码在失败之前有效。我尝试了clang,但也失败了......所以我一定做错了什么! 代码相当于: #i
用std::declval不是更好吗?声明形式: template T declval(); // (1) 然后是当前的: template T && declval(); // (2) std::c
用 C++17 标记,因为这是我引用的规范版本。 这是 IMO,标准的相关部分,第 23.15.7.6 节 [meta.trans.other]。 template struct common_ty
给定类型 A,B , 我关心 std::common_type 的确切定义, 不考虑可变参数 std::common_type对于任意类型 A... .所以让 using T = decltype(t
我正在将我的部分代码库从 C++11 升级到 C++14。我有几个数学实用函数,它们接受多个输入参数并返回一个 std::common_type_t 类型的值。 . 我正在考虑用一个简单的 auto
作为对我的 last question 的回答建议尽可能使用 std::common_type::type在自动返回类型的声明中而不是我原来的 decltype() .但是,这样做我遇到了问题(使用
common_type::type是 unsigned long因为关于积分提升后的操作数,标准说... [...] if the operand that has unsigned integer
我是一名优秀的程序员,十分优秀!