错误:可变参数模板类的类型不完整

蒂亚戈

我有代码:

#include <unordered_set>

template<typename First, typename Enable = void, typename ... T>
class converged_is_exactly_equal_functor;

template<typename ... T>
bool converged_is_exactly_equal(const T& ...);

template <typename T, typename std::enable_if<std::is_arithmetic<T>::value || std::is_enum<T>::value>::type* = nullptr>
bool is_exactly_equal(const T other, const T one) {
    return (other == one);
}

template<typename First, typename ... T>
class converged_is_exactly_equal_functor<First, std::enable_if<sizeof...(T) == 1>, T ...>
{
    private:
        static std::unordered_set<First*> visited_values;
        void visit_value (const First& value_to_visit) {
            visited_values.insert(&value_to_visit);
        }
        bool is_visited (const First& value_to_check) {
            return (visited_values.find(&value_to_check) != visited_values.end());
        }
    public:
        converged_is_exactly_equal_functor(void){}
        bool operator () (const First& first_arg, const T& ... expanded_args) const {
            if (!is_visited(first_arg)) {
                visit_value(first_arg);
                return is_exactly_equal(first_arg, expanded_args ...);
            }
            return true;
        }
};

template<typename First, typename ... T>
std::unordered_set<First*> converged_is_exactly_equal_functor<First, std::enable_if<sizeof...(T) == 1>, T ...>::visited_values;

template<typename First, typename ... T>
class converged_is_exactly_equal_functor<First, std::enable_if<sizeof...(T) != 1>, T ...>
{
    public:
        converged_is_exactly_equal_functor(void){}
        bool operator () (const First& first_arg, const T& ... expanded_args) const {
            return is_exactly_equal(first_arg, expanded_args ...);
        }
};

template<typename ... T>
bool converged_is_exactly_equal(const T& ... expanded_args) {
    converged_is_exactly_equal_functor<T ... > my_functor;
    return my_functor(expanded_args ...);
}

class a {
    public:
    a() : dbid(1), lsb(123) {}
    int dbid;
    long lsb;
};


bool operator == (const a& other, const a& one) {
    if (&other == &one)
        return true;
    return (
        converged_is_exactly_equal(other.dbid, one.dbid) &&
        converged_is_exactly_equal(other.lsb, one.lsb)
    );
}

int main(void) {
a as, bs;

as == bs;
}

鉴于类a是一组简单的原始类型,为什么我收到以下错误:

my_file.cxx: In instantiation of 'bool converged_is_exactly_equal(const T& ...) [with T = {long int, long int}]':
my_file.cxx:690:56:   required from here
my_file.cxx:682:48: error: 'converged_is_exactly_equal_functor<long int, long int> my_functor' has incomplete type
     converged_is_exactly_equal_functor<T ... > my_functor;

我认为该错误与专有数据结构无关,但是我看不出为什么类型可能不完整。我在同一文件中包含unordered_set的头文件。

is_exactly_equal(T)的所有定义都是在正向声明和模板的定义之间完成的。

请尽可能明确,因为我通常会发现理解模板错误很复杂。

我可以提供更多必要的信息,但是我明天才能回来。(这使我筋疲力尽:-/)

最高66

问题出在converged_is_exactly_equal_functor类及其使用上。

您声明如下

template<typename First, typename Enable = void, typename ... T>
class converged_is_exactly_equal_functor;

没有定义它。

然后定义两个专长:一个专为案例 sizeof...(T) == 1

template<typename First, typename ... T>
class converged_is_exactly_equal_functor<First, std::enable_if<sizeof...(T) == 1>, T ...>
{
  // ...
};

还有一种情况 sizeof...(T) != 1

template<typename First, typename ... T>
class converged_is_exactly_equal_functor<First, std::enable_if<sizeof...(T) != 1>, T ...>
 {
   // ...
 };

您在内部使用该类 converged_is_exactly_equal

template<typename ... T>
bool converged_is_exactly_equal(const T& ... expanded_args) {
    converged_is_exactly_equal_functor<T ... > my_functor;
    return my_functor(expanded_args ...);
}

在您的程序中被两次调用

    converged_is_exactly_equal(other.dbid, one.dbid) &&
    converged_is_exactly_equal(other.lsb, one.lsb)

第一次有两个int,第二次有两个long

在这两种情况下,您都converged_is_exactly_equal_functor使用第二个模板参数not声明一个void,因此它不匹配专业化,因此匹配主模板,但是声明了主模板但未定义。

这样的错误。

一种可能的解决方案:丢弃SFINAE部分,仅声明/定义以下类型的可变列表的类(旧的sizeof...(T) != 0

template <typename F, typename ... Ts>
class converged_is_exactly_equal_functor
 {
   public:
      converged_is_exactly_equal_functor ()
       { }

      bool operator () (F const & fa, Ts const & ... ea) const
       { return is_exactly_equal(fa, ea ...); }
 };

并仅针对两种情况(旧sizeof...(T) == 1情况)定义专门化

template <typename First, typename Second>
class converged_is_exactly_equal_functor<First, Second>
 {
   private:
      static std::unordered_set<First const *> visited_values;

      void visit_value (First const & value_to_visit) const
       { visited_values.insert(&value_to_visit); }

      bool is_visited (First const & value_to_check) const
       { return (visited_values.find(&value_to_check) != visited_values.end()); }

   public:
      converged_is_exactly_equal_functor ()
       { }

      bool operator () (First const & fa, Second const & sa) const
       {
            if ( false == is_visited(fa) )
             {
               visit_value(fa);

               return is_exactly_equal(fa, sa);
             }

            return true;
        }
 };

template <typename First, typename Second>
std::unordered_set<First const *> converged_is_exactly_equal_functor<First, Second>::visited_values;

观察到我已经添加了一些东西const来进行编译。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

模板类和“无效使用不完整类型”错误

将类作为函数参数传递时,C ++不完整类型错误

如何解决“参数类型不完整”错误?

类的前向声明导致不完整的类型错误

错误:模板:“ ...”是不完整或空的模板

使用不完整类型的函数模板的显式实例化

std::get on std::tuple 导致可变参数 args 因不完整的类型错误而减少到零

lang模板不完整类型

外部模板和不完整的类型

创建明确专门的模板类对象会产生“对象具有初始化但类型不完整”的错误

可变参数模板类的可变参数模板

C ++ 11翻译可变参数模板以推断类类型

类型取决于可变参数模板的类

参数类型 void 不完整?

指针和不完整的类类型

g ++错误:字段类型不完整

错误:字段的类型不完整

成员访问不完整类型错误

c + +模板使用模板内的类的指针的不完整类型

在参数列表中声明不完整的类型模板参数

const函数指针类型作为模板参数的“无效使用不完整类型”

如果事后定义类型,则实例化具有不完整类型的类模板吗?

错误:类型冲突,错误:形式参数2的类型不完整

类中不允许使用不完整的类型,但类模板中允许使用不完整的类型

非类型可变参数模板参数

这里如何将不完整类型用作向量的模板参数?

在类模板的成员函数中使用不完整类型

静态类模板成员:'sizeof'对不完整类型的无效应用

C ++聚合类型不完整,无法使用模板类定义