【发布时间】:2017-07-24 12:25:55
【问题描述】:
这是我正在迁移到 VS2017 的代码库的简化版本。 以下代码在 VS2013 和 Intel C++ 编译器 2017 update 4 中编译,但在 VS2013 中不编译。
#include <type_traits>
template<typename F, F f>
struct S1
{};
template<typename F, F f>
struct S2
{};
template<typename F, F f>
using BaseType = typename std::conditional<std::is_member_function_pointer<F>::value, S1<F, f>, S2<F, f>>::type;
template<typename Class, typename... Args>
Class * call_constructor(Args... args)
{
return new Class(args...);
}
template<class Class, typename... Args>
struct Constructor : BaseType<Class *(*)(Args...), call_constructor<Class, Args...>>
{
using ReturnType = Class *;
};
int main() {}
构造函数类的定义出现错误:
main.cpp(20): 错误 C2440: 'specialization': 无法从 'Class *(__cdecl *)(Args...)' 转换为 'Class *(__cdecl *)(Args...)' 注意:范围内具有此名称的函数都不匹配目标类型 注意:请参阅正在编译的类模板实例化“构造函数”的参考
如果我直接从 S1 或 S2 继承构造函数,错误就会消失。所以我认为问题在于 std::conditional 定义。
有什么想法吗?谢谢。
【问题讨论】:
-
template<class T>using type=T;然后struct Constructor : BaseType<type<Class*(Args...)>*, static_cast<type<Class*(Args...)>>(call_constructor<Class, Args...>>)试图将任何错误“向上”移动。恐怕您的代码仍在尝试确定call_constructor的重载,静态转换可能会有所帮助。 -
@Yakk 错误已更改 :) 错误 C2440: 'static_cast': 无法从 'Class *(__cdecl *)(Args...)' 转换为 'Class *(Args...)'
-
在静态演员表中加一颗星...
-
@Yarr 回到原来的 :( 'static_cast': 不能从 'Class *(__cdecl *)(Args...)' 转换为 'Class *(__cdecl *)(Args.. .)'
-
现在在
()中传递nullptr。这将消除是call_constructor导致问题的可能性。或者传递一个不是具有固定参数的模板的固定函数。 (目标是进一步简化您的代码,看看我们是否可以生成一个更简单的示例)
标签: c++ templates visual-studio-2017 variadic-templates template-specialization