有没有办法在编译时确定某个模板函数是否专用?如何检查模板函数是否专用?
例如,假设下面的功能:
template<size_t N>
void foo();
我要测试是否foo<42>
是专业。请注意,上面的声明不包含任何默认实现。
我试过SFINAE,但无法找到编译器无法从其声明中推断的函数的条件。
有什么想法?
感谢
有没有办法在编译时确定某个模板函数是否专用?如何检查模板函数是否专用?
例如,假设下面的功能:
template<size_t N>
void foo();
我要测试是否foo<42>
是专业。请注意,上面的声明不包含任何默认实现。
我试过SFINAE,但无法找到编译器无法从其声明中推断的函数的条件。
有什么想法?
感谢
有没有在编译时间,以确定是否有一定模板函数专门的方法吗?
带功能...我不这么认为。
但是,如果你创建一个仿函数,你可以添加一个静态const成员(is_specialized
,在下面的例子),可以给你这个信息
#include <iostream>
template <std::size_t N>
struct foo
{
static constexpr bool is_specialized { false };
void operator()() const
{ std::cout << "- generic (" << N << ") foo struct" << std::endl; }
};
template <>
struct foo<42U>
{
static constexpr bool is_specialized { true };
void operator()() const
{ std::cout << "- specialized (42) foo struct" << std::endl; }
};
int main()
{
foo<17U>()(); // print - generic (17) foo struct
foo<42U>()(); // print - specialized (42) foo struct
std::cout << foo<17U>::is_specialized << std::endl; // print 0
std::cout << foo<42U>::is_specialized << std::endl; // print 1
}
---编辑---
继Quentin的建议之后(再次感谢!)我开发了另一个基于函数的解决方案,它使用了一些东西来检测仿函数是泛型的还是专用的,仅在泛型仿函数中添加。在这种情况下,一个类型代替一个bool
常量。
template <std::size_t N>
struct foo
{
// im_not_specialized is added only in the generic version!
using im_not_specialized = void;
void operator()() const
{ std::cout << "- generic (" << N << ") foo struct" << std::endl; }
};
template <>
struct foo<42U>
{
void operator()() const
{ std::cout << "- specialized (42) foo struct" << std::endl; }
};
这种类型可以通过SFINAE使用,我提出了一种基于一个constexpr
isSpecialized()
模板函数的例子(具有辅助功能)
template <typename F>
constexpr bool isSpecializedHelper
(int, typename F::im_not_specialized const * = nullptr)
{ return false; }
template <typename F>
constexpr bool isSpecializedHelper (long)
{ return true; }
template <typename F>
constexpr bool isSpecialized()
{ return isSpecializedHelper<F>(0); }
这需要更多一点的工作,但isSpecialized()
可重复使用用不同的函子(im_not_specialized
类型的基于)
下面是一个完整的工作示例
#include <iostream>
template <std::size_t N>
struct foo
{
// im_not_specialized is added only in the generic version!
using im_not_specialized = void;
void operator()() const
{ std::cout << "- generic (" << N << ") foo struct" << std::endl; }
};
template <>
struct foo<42U>
{
void operator()() const
{ std::cout << "- specialized (42) foo struct" << std::endl; }
};
template <typename F>
constexpr bool isSpecializedHelper
(int, typename F::im_not_specialized const * = nullptr)
{ return false; }
template <typename F>
constexpr bool isSpecializedHelper (long)
{ return true; }
template <typename F>
constexpr bool isSpecialized()
{ return isSpecializedHelper<F>(0); }
int main()
{
foo<17U>()(); // print - generic (17) foo struct
foo<42U>()(); // print - specialized (42) foo struct
constexpr auto isSp17 = isSpecialized<foo<17U>>();
constexpr auto isSp42 = isSpecialized<foo<42U>>();
std::cout << isSp17 << std::endl; // print 0
std::cout << isSp42 << std::endl; // print 1
}
嗯,你在哪里和为什么要使用这样的东西?也许你最初的问题的更优雅的解决方案就在那里。 – DeiDei
那么,我不能使用重载和SFINAE,因为我有一个非类型的模板参数。然而,我可以在函数中添加一个未命名的'std :: integral_constant'。但我希望有一个更清洁的解决方案... –
非类型模板参数不会阻止您使用重载或SFINAE。目前还不清楚你为什么要检测这个。 – aschepler