gpt4 book ai didi

c++ - 错误 : Variadic template class has incomplete type

转载 作者:行者123 更新时间:2023-12-02 10:28:42 24 4
gpt4 key购买 nike

我有代码:

#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) 在前向声明和模板定义之间完成。
请尽可能明确,因为我倾向于发现一般来说理解模板错误很复杂。
我可以提供更多必要的信息,但我明天才回来。 (这个让我筋疲力尽:-/)

最佳答案

问题出在 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具有不是 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让它编译。

关于c++ - 错误 : Variadic template class has incomplete type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63183117/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com