C++ 元编程-未能专门化别名模板
第三次编辑: 今天,我收到了VS支持部门的电子邮件,表示这是一个已知问题,已在VS2017中修复。因此,我将坚持我的变通方法 我正在研究事件系统,我想使用一些元编程来节省键入的时间。代码如下:C++ 元编程-未能专门化别名模板,c++,template-meta-programming,C++,Template Meta Programming,第三次编辑: 今天,我收到了VS支持部门的电子邮件,表示这是一个已知问题,已在VS2017中修复。因此,我将坚持我的变通方法 我正在研究事件系统,我想使用一些元编程来节省键入的时间。代码如下: struct foo { using type = int; }; struct bar { using type = char; }; template<typename... Types> struct TypeList {}; //This and getScript are si
struct foo { using type = int; };
struct bar { using type = char; };
template<typename... Types> struct TypeList {};
//This and getScript are simplified, in reality the involve messier templates...
template<typename ReturnType>
struct ReqBuilder
{
using proxy = ReturnType(*)(void*, bool);
// ...
};
template<typename scriptType>
using getScript = ReqBuilder<scriptType>;
template<typename List, template<typename> typename Wrap> struct WrapTypeList_impl {};
template<typename...Ts, template<typename> typename Wrap> struct WrapTypeList_impl<TypeList<Ts...>, Wrap>
{
using type = TypeList<Wrap< Ts>...>;
};
template<typename List, template<typename> typename Wrap>
using WrapTypeList = typename WrapTypeList_impl<List, Wrap>::type;
//Use typedef
using list1 = TypeList<getScript<foo>, getScript<bar>>;
//Write it manually
using list2 = TypeList<ReqBuilder<foo>, ReqBuilder<bar>>;
//Use wrapper to wrap each element of typelist
using list3 = WrapTypeList<TypeList<foo, bar>, getScript>;
我真的不知道这意味着什么,但它可能与包扩展有关,因为当我添加此专门化时:
template<typename A,typename B, template<typename> typename Wrap>
struct WrapTypeList_impl<TypeList<A,B>, Wrap>
{
using type = TypeList<Wrap<A>,Wrap<B>>;
};
Erorrs:
1> Main.cpp
1>Main.cpp(23): error C2938: 'getScript<unknown-type>' : Failed to specialize alias template
1> Main.cpp(31): note: see reference to class template instantiation 'WrapTypeList_impl<TypeList<foo,bar>,getScript>' being compiled
1>Main.cpp(23): error C3546: '...': there are no parameter packs available to expand
1>Main.cpp(36): error C3203: 'TypeList': unspecialized class template can't be used as a template argument for template parameter '_Ty2', expected a real type
1>Main.cpp(37): error C3203: 'TypeList': unspecialized class template can't be used as a template argument for template parameter '_Ty2', expected a real type
1>Main.cpp(40): error C2338: list1 != list3
1>Main.cpp(41): error C2338: list2 != list3
1>Main.cpp
1> Main.cpp(23):错误C2938:“getScript”:未能专门化别名模板
1> cpp(31):注意:请参阅对正在编译的类模板实例化“WrapTypeList\u impl”的引用
1> Main.cpp(23):错误C3546:“…”:没有可扩展的参数包
1> Main.cpp(36):错误C3203:“类型列表”:非专用类模板不能用作模板参数“\u Ty2”的模板参数,应为实类型
1> Main.cpp(37):错误C3203:“类型列表”:非专用类模板不能用作模板参数“\u Ty2”的模板参数,应为实类型
1> Main.cpp(40):错误C2338:list1!=清单3
1> Main.cpp(41):错误C2338:list2!=清单3
在变量1解决后,为包装器添加所述A、B专门化
第二次编辑-找到解决方法
所以,最初的问题仍然存在,但经过一点尝试和错误,我尝试用单独的结构替换依赖类型,这似乎解决了问题:
template<typename scriptType>
struct getScript_impl
{
using type = ReqBuilder<typename scriptType::type>;
};
template<typename scriptType>
using getScript = typename getScript_impl<scriptType>::type;
/* REPLACING THIS WITH CODE ABOVE
template<typename scriptType>
using getScript = ReqBuilder<typename scriptType::type>;
*/
模板
结构getScript\u impl
{
使用type=ReqBuilder;
};
模板
使用getScript=typename getScript\u impl::type;
/*将此替换为上面的代码
模板
使用getScript=ReqBuilder;
*/
完整代码,在VS2015中对我有效:
正如我在评论中简要指出的,我认为问题在于使用dependent type作为另一个模板参数的alias template并没有实例化该模板或类似的东西(我不是模板向导,我只是戳一下它们,看看它们如何响应)
我发现很少有与此问题相关的链接,但还没有时间查看它们(;)。请在修改后提供实际导致错误的代码。简单地添加或替换
getScript
block似乎不会给出C2938。@VTT对此表示抱歉,添加了完整的代码和它引起的所有ERORR。我的目标是编写list3,它会自动扩展为更长的list1,然后扩展为更复杂的list2。第一件值得注意的事情是在表达式中使用list3=WrapTypeList代码>getScript在使用时没有模板参数列表,也没有任何默认参数。我在VS2015中遇到了同样的问题。谢谢你发布这个。你的变通方法可能帮我省去了好几天的头痛。
#include <algorithm>
struct foo { using type = int; };
struct bar { using type = char; };
template<typename... Types> struct TypeList {};
//This and getScript are simplified, in reality the involve messier templates...
template<typename ReturnType>
struct ReqBuilder
{
using proxy = ReturnType(*)(void*, bool);
// ...
};
template<typename scriptType>
using getScript = ReqBuilder<typename scriptType::type>;
template<typename List, template<typename> typename Wrap> struct WrapTypeList_impl {};
template<typename...Ts, template<typename> typename Wrap> struct WrapTypeList_impl<TypeList<Ts...>, Wrap>
{
using type = TypeList<Wrap<Ts>...>;
};
template<typename List, template<typename> typename Wrap>
using WrapTypeList = typename WrapTypeList_impl<List, Wrap>::type;
using list1 = TypeList<getScript<foo>, getScript<bar>>;
using list2 = TypeList<ReqBuilder<typename foo::type>, ReqBuilder<typename bar::type>>;
using list3 = WrapTypeList<TypeList<foo, bar>, getScript>;
int main()
{
constexpr bool A = std::is_same<list1, list2>::value;
constexpr bool B = std::is_same<list1, list3>::value;
constexpr bool C = std::is_same<list2, list3>::value;
static_assert(A, "list1 != list2");
static_assert(B, "list1 != list3");
static_assert(C, "list2 != list3");
}
1> Main.cpp
1>Main.cpp(23): error C2938: 'getScript<unknown-type>' : Failed to specialize alias template
1> Main.cpp(31): note: see reference to class template instantiation 'WrapTypeList_impl<TypeList<foo,bar>,getScript>' being compiled
1>Main.cpp(23): error C3546: '...': there are no parameter packs available to expand
1>Main.cpp(36): error C3203: 'TypeList': unspecialized class template can't be used as a template argument for template parameter '_Ty2', expected a real type
1>Main.cpp(37): error C3203: 'TypeList': unspecialized class template can't be used as a template argument for template parameter '_Ty2', expected a real type
1>Main.cpp(40): error C2338: list1 != list3
1>Main.cpp(41): error C2338: list2 != list3
template<typename scriptType>
struct getScript_impl
{
using type = ReqBuilder<typename scriptType::type>;
};
template<typename scriptType>
using getScript = typename getScript_impl<scriptType>::type;
/* REPLACING THIS WITH CODE ABOVE
template<typename scriptType>
using getScript = ReqBuilder<typename scriptType::type>;
*/