Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 元编程-未能专门化别名模板_C++_Template Meta Programming - Fatal编程技术网

C++ 元编程-未能专门化别名模板

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

第三次编辑: 今天,我收到了VS支持部门的电子邮件,表示这是一个已知问题,已在VS2017中修复。因此,我将坚持我的变通方法

我正在研究事件系统,我想使用一些元编程来节省键入的时间。代码如下:

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=WrapTypeListgetScript在使用时没有模板参数列表,也没有任何默认参数。我在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>;
*/