- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有这个嵌套的模板化结构:
template <typename... Ts>
struct A
{
template <unsigned i>
struct B
{
int b;
};
};
编译得很好。
然后我尝试定义这个函数。
template <unsigned i, typename... Ts>
void foo(A<Ts...>::B<i> var)
{
std::cout << var.b << std::endl;
}
出于某种原因我不完全理解,不会编译。我必须按以下方式更改它才能正常工作。
template <unsigned i, typename... Ts>
void foo(typename A<Ts...>::template B<i> var)
{
std::cout << var.b << std::endl;
}
但是,当我这样调用它时:
A<int, float>::B<0> var = {0};
foo(var);
它说模板参数i
不能被扣除。
我可以通过将模板参数显式添加到函数调用来使其工作:
A<int, float>::B<0> var = {0};
foo<0, int, float>(var);
这是为什么呢?我怎样才能做到不必在函数调用中指定模板参数?
最佳答案
因为标准是这么说的。
标准是这样说的,因为反转任意编译时映射等同于暂停。
它等同于 Halt,因为模板元编程是图灵完备的。
它是图灵完备的,因为实际上很难制作出非图灵完备的有用编程语言;它是偶然发生的,避免它会导致一种语言需要对看似简单的事情进行烦人的解决方法。
所以一般的问题是确定哪个A
A<int, float>::B<0>
来自和反转该映射是困难的,因此 C++ 标准表示编译器不会尝试。
如果您编写自己的映射,您就可以做到。首先,你必须意识到 B
类型没有“头发”,因为 B
的类型没有任何意义将其附加回 A
的类型用来创建它。我们可以加上“头发”:
template<class...Ts>
struct A {
template<unsigned i>
struct B {
using daddy = A;
int b;
};
};
现在我们可以找到A
来自 B<?>
的类型.
接下来让我们添加一些逆映射:
template<class...Ts>
struct types_t {using type=types_t;};
template<class X>
struct get_types;
template<class X>
using get_types_t=typename get_types<X>::type;
template<template<class...>class Z, class...Ts>
struct get_types<Z<Ts...>>:types_t<Ts...>{};
template<class B>
struct get_B_index;
template<unsigned i, template<unsigned>class B>
struct get_B_index<B<i>>:std::integral_constant<unsigned, i>{};
从这里我们可以得到A
的模板参数来自 B
:
template<class...Ts, unsigned i>
void foo( types_t<Ts...>, std::integral_constant<unsigned, i>, typename A<Ts...>::template B<i> var ) {
}
template<class B>
void foo( B b ) {
using types = get_types_t< typename B::daddy >;
using index = get_B_index< B >;
return foo( types{}, index{}, b );
}
关于c++ - 为什么不能为这个嵌套的模板化结构推断出这个函数的模板参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53270480/
基础问题 我要解决的基本问题是: 我有一个模板参数包 ArgTypes,我需要用包装在 std::optional 中的每个类型创建一个元组。例如:make_optional_tuple应该返回 st
我使用 createEntityAdapter 设置了一个简单的 redux store。初始状态包含实体、ID、状态、错误设置等 const carouselEventAdapter = creat
我有一些(遗留)代码,如下所示: void castFoo(string type, void* foo) { FooA* foo_a = NULL; FooB* foo_b = NULL;
我的代码是 const int *const ptrA = nullptr; auto *ptrB = &ptrA; 我对 const int *const ptrA 的看法是: (*
我目前正在尝试用 C++ 实现 XOR 链表。我尝试使用模板使其通用。编译时会弹出此错误,我无法解决这个问题。 我尝试使用模板在谷歌上搜索 XOR 链表,但到目前为止似乎还没有实现它。 异或链表.h:
我正在尝试找到一种方法来调用多个类成员函数,每个函数都有不同的参数,并且在调用前后会发生某些已知功能。 这个包装函数是我试过的,但是例如对它的最终调用不会编译错误: 'bool Wrapper(Wor
此代码在 上编译成功g++ ( Coliru ) ,但不是 Visual C++ ( rextester ) - 在线和我的桌面。 它是一个更大的 Visual Studio 2015 项目的简化版本
我正在尝试编写一个通用类,它传递一个键 key 对应于一组已知接口(interface)中的一个的键,稍后可以传递一个对象 thing 并类型安全地访问 thing[key]。这是我得到的: inte
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我是一名优秀的程序员,十分优秀!