单独的判决模板:teplate< ... sep ...>

时间:2017-03-15 10:28:18

标签: c++ templates c++17

我想在Ubuntu上使用clang++4.0分隔判决模板,我有以下代码:

#include <iostream>
#include <experimental/array>

using std::array;

struct Dummy {
};

template<int _I, int ... _rest>
constexpr bool test(int _test) {
if constexpr (sizeof...(_rest) == 0) {
    return (_test % _I);
} else {
    return (_test % _I && test<_rest...>(_test));
}
}

template< int ... _I>
constexpr array<int, sizeof...(_I)> make_array() {
return { {_I...}};
}

template<int ... _primes, typename _d, int _test, int ... _todo>
constexpr auto make_prime_array_helper() {
if constexpr (test<_primes...>(_test)) {
    if constexpr (sizeof...(_todo) == 0) {
        return make_array<_primes..., _test>();
    } else {
        return make_prime_array_helper<_primes..., _test, _d, _todo...>();
    }
} else {
    if constexpr (sizeof...(_todo) == 0) {
        return make_array<_primes...>();
    } else {
        return make_prime_array_helper<_primes..., _d, _todo...>();
    }
}
}

template<int _I0, int _I1,int _I2,int _I3, int ... _todo> // 0, 1, 2, 3 ....
constexpr auto make_prime_array() {
return make_prime_array_helper<_I2, _I3 , Dummy, _todo...>();
}

int main() {
constexpr auto a = make_prime_array<0, 1, 2, 3, 5>();
std::cout << a[1] << std::endl;
return 0;
}

但它不起作用,我收到错误:

../src/primearray.cpp:44:9: error: no matching function for call to 'make_prime_array_helper'
        return make_prime_array_helper<_I2, _I3 , Dummy, _todo...>();
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/primearray.cpp:49:21: note: in instantiation of function template specialization 'make_prime_array<0, 1, 2, 3, 5>' requested here
        constexpr auto a = make_prime_array<0, 1, 2, 3, 5>();
                           ^
../src/primearray.cpp:25:16: note: candidate template ignored: invalid explicitly-specified argument for template parameter '_primes'

我已尝试将typename _d更改为bool _d以外的其他内容,而不是我收到此错误:

../src/primearray.cpp:24:16: note: candidate template ignored: couldn't infer template argument '_d'

是否可以这样做?

1 个答案:

答案 0 :(得分:0)

您可以通过函数参数推导出一个模板参数包来完成此操作。例如。您对代码的以下小修改:

#include <iostream>
#include <experimental/array>

using std::array;

template<int... _primes> 
struct PrimeSeq {
};

template<int _I, int... _rest>
constexpr bool test(int _test) {
    if constexpr (sizeof...(_rest) == 0) {
        return (_test % _I);
    } else {
        return (_test % _I && test<_rest...>(_test));
    }
}

template< int ... _I>
constexpr array<int, sizeof...(_I)> make_array() {
    return { {_I...}};
}

template<int _test, int... _todo, int... _primes>
constexpr auto make_prime_array_helper(PrimeSeq<_primes...>) {
    if constexpr (test<_primes...>(_test)) {
        if constexpr (sizeof...(_todo) == 0) {
            return make_array<_primes..., _test>();
        } else {
            return make_prime_array_helper<_todo...>(PrimeSeq<_primes..., _test>{});
        }
    } else {
        if constexpr (sizeof...(_todo) == 0) {
            return make_array<_primes...>();
        } else {
            return make_prime_array_helper<_todo...>(PrimeSeq<_primes...>{});
        }
    }
}

template<int _I0, int _I1,int _I2,int _I3, int... _todo> // 0, 1, 2, 3 ....
constexpr auto make_prime_array() {
    return make_prime_array_helper<_todo...>(PrimeSeq<_I2, _I3>{});
}

int main() {
    constexpr auto a = make_prime_array<0, 1, 2, 3, 5>();
    std::cout << a[1] << std::endl;
    return 0;
}

将完成这项工作。通过clang++-4.0 -std=c++1z

编译时,它工作正常