c++ 是否可以显式示例化一个返回未指定类型的模板化函数?

qvtsj1bj  于 2022-12-20  发布在  其他
关注(0)|答案(1)|浏览(134)

我试图执行模板函数的显式示例化,以提高代码覆盖率结果的准确性。我知道在返回类型已知的情况下如何执行。我可以通过定义一个返回void的 Package 函数间接实现所需的结果。没有这个额外的函数定义是否可能实现这个结果?

#include <concepts>

template <typename T>
struct Gen {
    T operator()() const { return T{}; }
};
template <std::default_initializable T>
Gen<T> buildKnown() {
    return Gen<T>{};
}
template <std::default_initializable T>
std::invocable auto buildConstrained() {
    return Gen<T>{};
}
template <std::default_initializable T>
std::invocable auto buildInternal() /* -> decltype(??) */ {
    struct Local : Gen<T> {};
    return Local{};
}

// Perform explicit instantiation of each templated function.
template Gen<int> buildKnown<int>();        // works
template Gen<int> buildConstrained<int>();  // somewhat surprised this doesn't work.
template auto buildInternal<int>();         // not surprised this doesn't work

// Indirectly instantiate buildInternal through a wrapper function.
template <typename T> void buildInternalWrapper() { buildInternal<T>(); }
template void buildInternalWrapper<int>();

编辑:修正了使问题更混乱的类型约束(最初是std::invocable<int>)。

tv6aics1

tv6aics11#

首先,你推导出的返回类型约束是错误的,比如你写的这个函数模板:

template <std::default_initializable T>
std::invocable<T> auto buildConstrained() {
    return Gen<T>{};
}

如果用T = int示例化会发生什么?

std::invocable<int> auto buildConstrained() {
    return Gen<int>{};
}

占位符类型说明符std::invocable<int> auto意味着类型需要被推导,并且,如果我们把这个推导出的类型称为U,那么约束std::invocable<U, int>必须被满足,所以这个函数定义只有在std::invocable<Gen<int>, int>被满足的情况下才是合式的。Gen<int>可以用0个参数调用,而不能用1个int参数调用。
我猜你的意思是

template <std::default_initializable T>
std::invocable auto buildConstrained() {
    return Gen<T>{};
}

做了这样的修改之后,我们现在可以声明显式示例化:

template std::invocable auto buildConstrained<int>();

使用占位符类型说明符的函数模板的显式示例化也必须使用相同的占位符类型说明符,而不是推导类型。

相关问题