[英]How can I resolve Error: variable template-id 'complex type' in nested-name-specifier
首先,讓我們定義問題。 在一個較大的項目中,我們有很多 class 類型。 一堆這些類型是由我們不控制 output 的工具生成的。 這意味着我們無法控制它們的 inheritance 鏈,它們的實現可能非常復雜。 還有現有的工具可以使用宏智能地推出這些類型,以構建復雜的結構,例如復雜的 switch case 語句,以及模板無法解決的其他重復實現。 但我希望盡可能地增加類型系統的彈性和安全性。 因此,我還希望能夠利用 TypeLists 和帶有 static 斷言的 type_traits 來限制具有清晰可讀的錯誤消息的某些接口。 但是,我在編寫將這些類型分組為集群的代碼時遇到了很多麻煩,而且我不理解標題中提到的錯誤。 我給出這個上下文以防我遇到一個明顯的 XY 問題,但這似乎是迄今為止我發現的最有希望的路徑。
到目前為止,這是代碼的簡化版本,我注釋掉了某些包含,以便您可以將其復制粘貼為一個塊進行測試,但將它們保留為注釋,以便您了解在真實示例中應該如何鏈接。 為簡潔起見,我還排除了 header 防護裝置,但假設標題將具有標准 header 防護裝置:
// AStruct.hpp
// special group of 'A' structs (assume these are complex types and we can't control their inheritance chain)
struct A0{};
struct A1{};
struct A2{};
struct A3{};
struct A4{};
struct A5{};
struct A6{};
struct A7{};
struct A8{};
struct A9{};
// BStruct.hpp
// special group of 'B' structs (assume these are complex types and we can't control their inheritance chain)
struct B0{};
struct B1{};
struct B2{};
struct B3{};
struct B4{};
struct B5{};
struct B6{};
struct B7{};
struct B8{};
struct B9{};
// TypeList.hpp
#include <type_traits>
template<typename ... Types>
struct TypeList;
template<template <typename T, typename U> typename Evaluator, typename Term, typename Head, typename ... Tail> struct OneOf;
template<template <typename T, typename U> typename Evaluator, typename Term, typename Head> struct OneOf<Evaluator, Term, TypeList<Head> >
{
using value = std::bool_constant<Evaluator<Term, Head>::value>;
};
template<template <typename T, typename U> typename Evaluator, typename Term, typename Head, typename ... Tail> struct OneOf<Evaluator, Term, TypeList<Head, Tail...> >
{
using value = std::bool_constant<Evaluator<Term, Head>::value || OneOf<Evaluator, Term, TypeList<Tail...> >::value>;
};
template<template <typename T, typename U> typename Evaluator, typename Term, typename Head, typename ... Tail >
inline constexpr bool OneOfV = OneOf<Evaluator, Term, TypeList<Head, Tail...> >::value;
// AStructUtils.hpp
// #include TypeList.hpp
// #include AStruct.hpp
// This is setup as a macro so that other macros can consume it in addition
// to templates with TypeList
#define A_STRUCT_TYPES \
A0, \
A1, \
A2, \
A3, \
A4, \
A5, \
A6, \
A7, \
A8, \
A9
template<typename AStruct>
using AStructTypes = TypeList <A_STRUCT_TYPES>;
template< typename AStruct >
inline constexpr bool IsAStructV = OneOfV<std::is_same, AStruct, AStructTypes >::value;
// BStructUtils.hpp
// #include TypeList.hpp
// #include BStruct.hpp
// This is setup as a macro so that other macros can consume it in addition
// to templates with TypeList
#define B_STRUCT_TYPES \
B0, \
B1, \
B2, \
B3, \
B4, \
B5, \
B6, \
B7, \
B8, \
B9
template<typename BStruct>
using BStructTypes = TypeList <B_STRUCT_TYPES>;
template< typename BStruct >
inline constexpr bool IsBStructV = OneOfV<std::is_same, BStruct, BStructTypes >::value;
// Driver main.cpp includes
// #include AStructUtils.hpp
// #include BStructUtils.hpp
#include <string>
#include <iostream>
int main()
{
std::string buffer;
buffer.append( "A4 is a AStruct type: " + std::to_string( IsAStructV<A4> ) + "\n" ); // 1
buffer.append( "B4 is a AStruct type: " + std::to_string( IsAStructV<B4> ) + "\n" ); // 0
buffer.append( "A4 is a BStruct type: " + std::to_string( IsBStructV<A4> ) + "\n" ); // 0
buffer.append( "B4 is a BStruct type: " + std::to_string( IsBStructV<B4> ) + "\n" ); // 1
std::cout << buffer << std::flush;
}
這是完整的錯誤:
:68:36: 錯誤:變量模板 id 'OneOfV struct std::is_same, AStruct, template using AStructTypes = TypeList >' in nested-name-specifier
這是 GodBolt 中的示例: https://godbolt.org/z/Mber5YToY
將類型別名為value
有點不尋常。 相反,我建議您將其聲明為 static 成員,以便您可以使用變量模板直接提取它。
template<template <typename T, typename U> typename Evaluator, typename Term, typename Head, typename ... Tail> struct OneOf;
template<template <typename T, typename U> typename Evaluator, typename Term, typename Head> struct OneOf<Evaluator, Term, TypeList<Head> >
{
static inline constexpr bool value = std::bool_constant<Evaluator<Term, Head>::value>::value;
};
template<template <typename T, typename U> typename Evaluator, typename Term, typename Head, typename ... Tail> struct OneOf<Evaluator, Term, TypeList<Head, Tail...> >
{
static inline constexpr bool value = Evaluator<Term, Head>::value || OneOf<Evaluator, Term, TypeList<Tail...> >::value;
};
在您的情況下,變量模板OneOfV
的模板參數應該與Oneof
完全相同。
template<template <typename T, typename U> typename Evaluator, typename Term, typename Head, typename ... Tail >
inline constexpr bool OneOfV = OneOf<Evaluator, Term, Head, Tail...>::value;
否則, IsAStructV<A4>
將擴展為OneOf<std::same_as, A4, TypeList<AStructTypes>>::value
,其中第三個參數應為AStructTypes
。
此外, AStructTypes
沒有理由成為模板。 這是一個確定的類型。 BStructTypes
也是如此。
using AStructTypes = TypeList <A_STRUCT_TYPES>;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.