有什么方法可以进行部分专业化?

There is any way to do a partial specialization?

只是为了好玩,我正在尝试使用模板实现编译时 pow2 函数。 实际上,我可以这样做:

template <std::size_t n, typename type_t>
struct custom
{
    static type_t pow(type_t b) { return b * custom<n - 1, type_t>::pow(b); }
};

template <typename type_t>
struct custom<0, type_t>
{
    // (void)b; to avoid unused warning.
    static type_t pow(type_t b) { (void) b; return static_cast<type_t>(1); }
};

这样就可以了,但我的方法是这样想的:

template <std::size_t n, typename type_t>
type_t cus_pow(type_t b) { return b * cus_pow<n - 1, type_t>(b); }

// This doesn't exists.
template <0, typename type_t>
type_t cus_pow(type_t b) { (void) b; return 1; }

因为如果我想创建任何部分元编程函数,就被迫创建一个结构,它看起来太多了。

那么,有什么方法可以只用一个函数进行部分元编程吗?

您不能部分专业化 function/method。

您可以使用 if constexpr (C++17) 来避免重复:

static type_t pow([[maybe_unused]]type_t b) {
    if constexpr (n == 0) {
        return static_cast<type_t>(1); }
    } else {
        return b * custom<n - 1, type_t>::pow(b);
    }
}

没有额外的运行时分支。

So, there is any way to do partial metaprogramming just with one function?

否:您不能部分特化模板函数。

但是还有其他方法可以解决这个问题。

如果你可以使用 C++17,一个优雅的解决方案是使用 if constexpr(参见 Jarod42 的回答)。

在C++17之前,可以使用SFINAE

template <std::size_t n, typename type_t>
std::enable_if_t<n == 0u, type_t> cus_pow (type_t)
 { return 1; }

template <std::size_t n, typename type_t>
std::enable_if_t<n != 0u, type_t> cus_pow (type_t b)
 { return b * cus_pow<n - 1, type_t>(b); }

到 enable/disable 零版本或非零版本,根据 n 的值(并定义(或至少声明)零版本 before, 假设非零版本可以调用它)。

另一种解决方案可以是标签调度

template <std::size_t, typename type_t>
type_t cus_pow (std::true_type, type_t)
 { return 1; }

template <std::size_t n, typename type_t>
type_t cus_pow (std::false_type, type_t b)
 { return b * cus_pow<n-1u, type_t>(std::integral_constant<bool, n-1u==0u>{}, b); }

template <std::size_t n, typename type_t>
type_t cus_pow (type_t b)
 { return cus_pow<n>(std::integral_constant<bool, n==0u>{}, b); }

调用另一个带有“标签”(std::true_typestd::false_type)的函数,说明 n 是否为零。