我有一个模板函数,可以通过参数包进行递归。本质上,它旨在将something.Get<A,B,C>()
映射到something.Get<A>().Get<B>().Get<C>()
。
这可以通过(完全独立的源码)来实现
template <typename... Pack> class Struct {
std::tuple<Pack...> mTuple;
template <typename Type> auto &GetRef_internal() {
return std::get<first_true<std::is_same<Type, Pack>::value...>::value>(
mTuple);
}
public:
template <typename Current> Current &GetRef() {
return GetRef_internal<Current>();
}
template <typename Current, typename... Next,
typename std::enable_if<sizeof...(Next) != 0>::type * = nullptr>
auto &GetRef() {
auto current = GetRef_internal<Current>();
return current.GetRef<Next...>();
}
};
其中first_true
返回第一个元素的索引为真。
这用g ++编译,似乎在MSVC上使用online compiler编译。使用clang ++进行编译时,我得到以下错误:
test.cxx:40:31: error: expected '(' for function-style cast or type construction
return current.GetRef<Next...>();
~~~~^
test.cxx:38:9: error: cannot deduce return type 'auto &' for function with no return statements
auto &GetRef() {
^
test.cxx:48:12: note: in instantiation of function template specialization 'Struct<Struct<int, Struct<float, float> >, Struct<char>, int>::GetRef<Struct<int, Struct<float, float> >, Struct<float, float> , nullptr>' requested here
.GetRef<Struct<int, Struct<float, float>>, Struct<float, float>>();
^
2 errors generated.
是什么导致这种情况?
P.S。实际的生产代码&#39;比示例看起来更有用,但是这里发布的内容太多了。
=============================================== ==========================
#include <tuple>
#include <type_traits>
// Template to check if condition holds true for all members of a parameter
// pack.
template <bool... b> struct BoolArray {};
template <bool... b>
using all_true = std::is_same<BoolArray<b...>, BoolArray<(b, true)...>>;
//helper type trait
template <bool... b> struct first_true {
template <
unsigned index = 0,
typename std::enable_if<index<sizeof...(b)-1>::type * =
nullptr> static constexpr unsigned check() {
return std::get<index>(std::make_tuple(b...)) ? index : check<index + 1>();
}
template <unsigned index = 0,
typename std::enable_if<index >= sizeof...(b)-1>::type * = nullptr>
static constexpr unsigned check() {
return std::get<index>(std::make_tuple(b...)) ? index : 0;
}
static constexpr unsigned value = first_true<b...>::check();
};
//The actual problem struct
template <typename... Pack> class Struct {
std::tuple<Pack...> mTuple;
template <typename Type> auto &GetRef_internal() {
return std::get<first_true<std::is_same<Type, Pack>::value...>::value>(
mTuple);
}
public:
template <typename Current> Current &GetRef() {
return GetRef_internal<Current>();
}
template <typename Current, typename... Next,
typename std::enable_if<sizeof...(Next) != 0>::type * = nullptr>
auto &GetRef() {
auto current = GetRef_internal<Current>();
return current.GetRef<Next...>();
}
};
int main() {
// Define a random nested struct
Struct<Struct<int, Struct<float, float>>, Struct<char>, int> myStruct;
// Then retrieve one of the substructures to instantiate the template
auto substruct =
myStruct
.GetRef<Struct<int, Struct<float, float>>, Struct<float, float>>();
return 0;
}
答案 0 :(得分:0)
current.GetRef<Next...>
是从属名称,因此您需要使用GetRef
关键字指定template
为模板命名:
return current.template GetRef<Next...>();
有关从属名称的详细信息,请参阅Where and why do I have to put the "template" and "typename" keywords?。