【发布时间】:2020-07-31 00:09:04
【问题描述】:
我有代码:
#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;
}
鉴于 class 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) 的所有定义都在前向声明和模板定义之间完成。
请尽可能明确,因为我倾向于发现一般来说理解模板错误很复杂。
我可以提供更多必要的信息,但我明天才会回来。 (这个让我筋疲力尽:-/)
【问题讨论】:
-
请同时提供实例化模板的代码。我假设
operator==应该是模板化的? -
我不明白。我相信实例化模板的代码就在那里。 "operator==" 是一一定义的,因为它涵盖了每个不同结构的成员比较。
-
没有实例化,它似乎编译fine。 (我制作了
operator==一个模板)。它不是提供的代码中的类模板的成员。当然,有可能我误解了这个问题。 -
我们需要的是minimal reproducible example,我们可以自己编译以重现错误。为了查看我们是否遇到相同的错误,我们每个人都需要添加适当的包含并选择一种方法来处理
operator==中使用的缺失类。 -
我添加了 main 和实例化,产生了同样的错误。将更新问题。
标签: c++ templates variadic-templates sfinae