Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++_Templates_C++11_Variadic Templates_Sfinae - Fatal编程技术网

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;