C++ 为什么模板实例化在这里永远持续?
在下面的代码中,我想替换C++ 为什么模板实例化在这里永远持续?,c++,templates,c++11,variadic-templates,sfinae,C++,Templates,C++11,Variadic Templates,Sfinae,在下面的代码中,我想替换 template <typename T, typename... Args> auto check (rank<1,T>, Args... args) const -> std::enable_if_t<!has_argument_type<T, Args...>(), decltype(check(rank<2, Ts...>{}, args...))> { return ch
template <typename T, typename... Args>
auto check (rank<1,T>, Args... args) const
-> std::enable_if_t<!has_argument_type<T, Args...>(), decltype(check(rank<2, Ts...>{}, args...))> {
return check(rank<2, Ts...>{}, args...); // Since rank<1,T> derives immediately from rank<2, Ts...>.
}
template <typename T, typename... Args>
auto check (rank<2,T>, Args... args) const
-> std::enable_if_t<!has_argument_type<T, Args...>(), decltype(check(rank<3, Ts...>{}, args...))> {
return check(rank<3, Ts...>{}, args...); // Since rank<2,T> derives immediately from rank<3, Ts...>.
}
// etc... until rank<9>.
偏序直到重载解决过程的很晚才开始生效 忽略各种
检查
重载中的所有乒乓球,最终会导致
template <std::size_t N, typename T, typename... Args>
auto check (rank<N,T>, Args... args) const
-> std::enable_if_t<!has_argument_type_n<T, N, Args...>(),
decltype(check(rank<N+1, Ts...>{}, args...))>;
template <typename T, typename... Args>
auto check (rank<10, T>, Args... args) const;
模板
自动检查(秩、参数…参数)常量
->std::启用_if_t(),
decltype(检查(秩{},args…)>;
模板
自动检查(秩,参数…参数)常量;
对于
rank,偏序直到重载解析过程的很晚才生效
忽略各种检查
重载中的所有乒乓球,最终会导致
template <std::size_t N, typename T, typename... Args>
auto check (rank<N,T>, Args... args) const
-> std::enable_if_t<!has_argument_type_n<T, N, Args...>(),
decltype(check(rank<N+1, Ts...>{}, args...))>;
template <typename T, typename... Args>
auto check (rank<10, T>, Args... args) const;
模板
自动检查(秩、参数…参数)常量
->std::启用_if_t(),
decltype(检查(秩{},args…)>;
模板
自动检查(秩,参数…参数)常量;
通过rankCan,您可以提供实际编译的东西吗?“我不知道你的代码应该做什么。@Brian代码是在GCC 5.3上编译的。如果您查看main(),我只是使用工厂类创建对象。根据类的参数类型
成员类型对要创建的内容进行排序。我只是问如何缩短代码的重复部分(注释掉的部分是我想要使用的,但不明白为什么它不起作用)。你的检查了吗(rank,
函数真的什么也不返回,或者你只是用cout@VolkerK替换了实际的代码,它真的只是为了终止实例化。重载可能永远不会达到。但即使它什么也不返回,也不应该影响main()中的测试。),因为我没有在这个测试的任何地方存储创建的对象。在生产代码中,我可能会返回一个nonesuch{}
对象。请发布一个。在您的代码中至少发现了一个不相关的打字错误。删除所有不会导致错误消失的内容。我指的是所有内容。如果您将其从类中删除,问题是否仍会发生,并且无法解释?好的,将其从类中删除。如果您删除参数…
并进行更改enable\u if\u t
对于更简单的东西,它仍然会发生吗?然后去掉它们。它需要10个,还是1个就足够了?然后将其设为1。你需要看似不相关的模板代码页吗?删除它,并在没有它的情况下导致错误。你能提供一些实际编译的东西吗?我不知道你的代码是什么Brian代码是在GCC 5.3上编译的。如果你查看main(),我只是在用工厂类创建对象。根据类的参数\u type
成员类型对要创建的对象进行排序。我只是问如何缩短代码的重复部分(注释掉的部分是我想要使用的,但不明白为什么它不起作用。)你的检查了吗(rank,
函数真的什么也不返回,或者你只是用cout@VolkerK替换了实际的代码,它真的只是为了终止实例化。重载可能永远不会达到。但即使它什么也不返回,也不应该影响main()中的测试。),因为我没有在这个测试的任何地方存储创建的对象。在生产代码中,我可能会返回一个nonesuch{}
对象。请发布一个。在您的代码中至少发现了一个不相关的打字错误。删除所有不会导致错误消失的内容。我指的是所有内容。如果您将其从类中删除,问题是否仍会发生,并且无法解释?好的,将其从类中删除。如果您删除参数…
并进行更改启用\u如果\u t
到更简单的地方,它还会发生吗?然后去掉它们。它需要10个,还是1个就足够了?然后将其设为1。你需要看似不相关的模板代码页面吗?删除它,并在没有它的情况下导致错误。
#include <iostream>
#include <type_traits>
#include <tuple>
template <typename T>
constexpr auto has_argument_type_impl(int)
-> decltype(typename T::argument_type{}, std::true_type{});
template <typename T>
constexpr auto has_argument_type_impl(long) -> std::false_type;
template <typename T>
constexpr bool has_argument_type() { return decltype(has_argument_type_impl<T>(0))::value; }
template <typename... Ts>
class Factory {
template <std::size_t, typename...> struct rank;
template <std::size_t N, typename First, typename... Rest>
struct rank<N, First, Rest...> : rank<N, Rest...> {};
template <std::size_t N, typename T> struct rank<N,T> : rank<N+1, Ts...> {};
template <typename T> struct rank<10, T> {}; // Need to end the instantiations somewhere.
public:
template <typename... Args>
decltype(auto) create (Args... args) const {
return check(rank<0, Ts...>{}, args...);
}
private:
template <std::size_t N, typename T, typename... Rest, typename... Args>
auto check (rank<N, T, Rest...>, Args... args) const
-> std::enable_if_t<has_argument_type<T>(), decltype(T(args...))> {
return T(args...);
}
template <std::size_t N, typename T, typename... Rest, typename... Args>
auto check (rank<N, T, Rest...>, Args... args) const
-> std::enable_if_t<!has_argument_type<T>(), decltype(check(rank<N, Rest...>{}, args...))> {
return check(rank<N, Rest...>{}, args...);
}
template <typename T, typename... Args>
auto check (rank<0,T>, Args... args) const
-> std::enable_if_t<!has_argument_type<T>(), decltype(check(rank<1, Ts...>{}, args...))> {
return check(rank<1, Ts...>{}, args...); // Since rank<0,T> derives immediately from rank<1, Ts...>.
}
// I want to use the following instead of what's below it.
// template <std::size_t N, typename T, typename... Args>
// auto check (rank<N,T>, Args... args) const
// -> std::enable_if_t<!has_argument_type<T>(), decltype(check(rank<N+1, Ts...>{}, args...))> {
// return check(rank<N+1, Ts...>{}, args...); // Since rank<N,T> derives immediately from rank<N+1, Ts...>.
// }
//
// template <typename T, typename... Args>
// auto check (rank<10, T>, Args... args) const { std::cout << "Nothing found.\n"; }
template <typename T, typename... Args>
auto check (rank<1,T>, Args... args) const
-> std::enable_if_t<!has_argument_type<T>(), decltype(check(rank<2, Ts...>{}, args...))> {
return check(rank<2, Ts...>{}, args...); // Since rank<1,T> derives immediately from rank<2, Ts...>.
}
template <typename T, typename... Args>
auto check (rank<2,T>, Args... args) const
-> std::enable_if_t<!has_argument_type<T>(), decltype(check(rank<3, Ts...>{}, args...))> {
return check(rank<3, Ts...>{}, args...); // Since rank<2,T> derives immediately from rank<3, Ts...>.
}
// etc... until rank<9>.
};
// Testing
struct Object {};
struct Thing {};
struct Blob {
using argument_type = std::tuple<int, double>;
Blob (int, double) { std::cout << "Blob\n"; }
};
int main() {
Factory<Object, Thing, Blob>().create(4,3.5); // Blob
}
template <std::size_t N, typename T, typename... Args>
auto check (rank<N,T>, Args... args) const
-> std::enable_if_t<!has_argument_type_n<T, N, Args...>(),
decltype(check(rank<N+1, Ts...>{}, args...))>;
template <typename T, typename... Args>
auto check (rank<10, T>, Args... args) const;