首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编译时的主要因素列表:专门化错误

编译时的主要因素列表:专门化错误
EN

Stack Overflow用户
提问于 2013-11-07 14:17:59
回答 2查看 281关注 0票数 0

考虑以下代码(链接到依佩恩):

代码语言:javascript
复制
#include <iostream>
#include <type_traits>

// List of factors
template<std::intmax_t ... Misc> 
struct factors { };

// Declaration
template<std::intmax_t ... Misc> 
struct factorization;

// Initial specialization
template<std::intmax_t Value> 
struct factorization<Value>
{
    typedef typename std::conditional<Value % 2 == 0,
            typename factorization<Value / 2, 2, 2>::type,
            typename factorization<Value / 2, 2 + 1>::type>::type type;
};

// Initial specialization when the value is not divisible by 2
template<std::intmax_t Value, std::intmax_t Divisor> 
struct factorization<Value, Divisor>
{
    typedef typename std::conditional<Value % Divisor == 0,
            typename factorization<Value / Divisor, Divisor, Divisor>::type,
            typename factorization<Value / Divisor, Divisor + 1>::type>::type type;
};

// Specialization after the first recusion step
template<std::intmax_t Value, std::intmax_t Divisor, std::intmax_t Prime> 
struct factorization<Value, Divisor, Prime>
{
    typedef typename std::conditional<Value % Divisor == 0,
            typename factorization<Value / Divisor, Divisor, Divisor>::type,
            typename factorization<Value / Divisor, Divisor + 1>::type>::type type;
};

// Recursion specialization
template<std::intmax_t Value, std::intmax_t Divisor, std::intmax_t Prime, std::intmax_t ... Primes> 
struct factorization<Value, Divisor, Prime, Primes...>
{
    typedef typename std::conditional<Value % Divisor == 0 && Divisor != Prime,
            typename factorization<Value / Divisor, Divisor, Divisor, Prime,
                    Primes...>::type,
            typename factorization<
                    Value % Divisor == 0 ? Value / Divisor : Value,
                    Divisor + (Value % Divisor != 0), Prime, Primes...>::type>::type type;
};

// Last recursion step
template<std::intmax_t Value, std::intmax_t ... Primes> 
struct factorization<Value, Value, Primes...>
{
    typedef typename factorization<1, Value, Value, Primes...>::type type;
};

// Finalize
template<std::intmax_t Divisor, std::intmax_t ... Primes> 
struct factorization<1, Divisor, Primes...>
{
    typedef factors<Primes...> type;
};

// Main
int main() {
    typename factorization<18>::type x;
    return 0;
}

这段代码应该列出一个数字的素数,不重复:例如,factorization<18>::type应该等于factors<2, 3>

但是,如果出现以下错误,则会失败:

代码语言:javascript
复制
prog.cpp: In instantiation of ‘struct factorization<4ll, 2ll, 2ll>’:
prog.cpp:36:79:   required from ‘struct factorization<9ll, 2ll, 2ll>’
prog.cpp:18:67:   required from ‘struct factorization<18ll>’
prog.cpp:67:28:   required from here
prog.cpp:36:79: error: ambiguous class template instantiation for ‘struct factorization<2ll, 2ll, 2ll>’
             typename factorization<Value / Divisor, Divisor + 1>::type>::type type;
                                                                               ^
prog.cpp:32:8: error: candidates are: struct factorization<Value, Divisor, Prime>
 struct factorization<Value, Divisor, Prime>
        ^
prog.cpp:41:8: error:                 struct factorization<Value, Divisor, Prime, Primes ...>
 struct factorization<Value, Divisor, Prime, Primes...>
        ^
prog.cpp:53:8: error:                 struct factorization<Value, Value, Primes ...>
 struct factorization<Value, Value, Primes...>
        ^
prog.cpp:36:79: error: invalid use of incomplete type ‘struct factorization<2ll, 2ll, 2ll>’
             typename factorization<Value / Divisor, Divisor + 1>::type>::type type;
                                                                               ^
prog.cpp:10:8: error: declaration of ‘struct factorization<2ll, 2ll, 2ll>’
 struct factorization;
        ^
prog.cpp: In function ‘int main()’:
prog.cpp:67:30: error: invalid combination of multiple type-specifiers
  typename factorization<18>::type x;
                              ^
prog.cpp:67:36: error: invalid type in declaration before ‘;’ token
  typename factorization<18>::type x;
                                    ^
prog.cpp:67:35: warning: unused variable ‘x’ [-Wunused-variable]
  typename factorization<18>::type x;
                                   ^

Compilation error   time: 0 memory: 0 signal:0

prog.cpp: In function ‘int main()’:
prog.cpp:67:30: error: ‘type’ in ‘struct factorization<18ll>’ does not name a type
  typename factorization<18>::type x;
                              ^
prog.cpp:67:36: error: invalid type in declaration before ‘;’ token
  typename factorization<18>::type x;
                                    ^
prog.cpp:67:35: warning: unused variable ‘x’ [-Wunused-variable]
  typename factorization<18>::type x;
                                   ^

如何解决这个问题?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-07 14:28:50

没有与factorization<18>匹配的专门化(据我所知),除非您省略了一些代码。您的每个专门化似乎都假定至少有两个参数被传递到分解中。

从您添加的注释中可以看出,您假设标记为“初始专门化”的专门化只需传递一个数字即可。这不是真的。试着运行factorization<18, 2>来查看它的实际运行情况。如果这确实是您想要的,那么要么省略专门化中的2并保持主体不变,要么添加一个在单个数字上匹配并将type设置为typename factorization<N, 2>::type的最终专门化。

票数 1
EN

Stack Overflow用户

发布于 2013-11-07 16:30:44

这是一个有用的版本。请注意,使用std::conditional是个坏主意,因为两个分支仍然需要扩展。专业化工作要好得多。

代码语言:javascript
复制
// List of factors
template<std::intmax_t...> 
struct factors { };

// Declaration
template<bool no_remainder, std::intmax_t Value, std::intmax_t Divisor, std::intmax_t ... Primes> 
struct factorization_remove_repeated;
template<bool no_remainder, std::intmax_t Value, std::intmax_t Divisor, std::intmax_t ... Primes> 
struct factorization_check;

// wraps the remainder check to reduce code duplication
template<template<bool, std::intmax_t ...> class T, std::intmax_t Value, std::intmax_t Divisor, std::intmax_t ...Primes> 
struct factorization_advance
{
    typedef typename T<(Value % Divisor) == 0, Value, Divisor, Primes...>::type type;
};

// end case
template<template<bool, std::intmax_t ...> class T, std::intmax_t Divisor, std::intmax_t ... Primes> 
struct factorization_advance<T, 1, Divisor, Primes...>
{
    typedef factors<Primes...> type;
};

// No more repeats of Divisor, move to Divisor+1
template<std::intmax_t Value, std::intmax_t Divisor, std::intmax_t ... Primes> 
struct factorization_remove_repeated<false, Value, Divisor, Primes...>
{
    typedef typename factorization_advance<factorization_check, Value, Divisor + 1, Primes...>::type type;
};

// removed a repeat of Divisor, continue doing so, without adding to primes list
template<std::intmax_t Value, std::intmax_t Divisor, std::intmax_t ... Primes>
struct factorization_remove_repeated<true, Value, Divisor, Primes...>
{
    typedef typename factorization_advance<::factorization_remove_repeated, Value / Divisor, Divisor, Primes...>::type type;
};

// found that Divisor isn't a factor, move to Divisor+1
template<std::intmax_t Value, std::intmax_t Divisor, std::intmax_t ... Primes> 
struct factorization_check<false, Value, Divisor, Primes...>
{
    typedef typename factorization_advance<::factorization_check, Value, Divisor + 1, Primes...>::type type;
};

// Found first occurrence of a factor, add to primes list, remove repeats
template<std::intmax_t Value, std::intmax_t Divisor, std::intmax_t ... Primes>
struct factorization_check<true, Value, Divisor, Primes...>
{
    typedef typename factorization_advance<factorization_remove_repeated, Value / Divisor, Divisor, Primes..., Divisor>::type type;
};

// Convenience wrapper
template<std::intmax_t Value> 
struct factorization
{
    typedef typename factorization_advance<factorization_check, Value, 2>::type type;
};
  • 演示:http://rextester.com/NPGBU58803
  • 早期版本,也能工作,但维护性较差,IMO:http://ideone.com/Ia9hnd
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19838202

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档