如果我有一个包含两个模板参数的类,是否有任何方法可以仅在其中一个参数上分支if constexpr?在下面的示例中,我可以测试两个参数是否匹配,但是我想用一种方法来匹配以char为第一个参数的MyTemplateClass的任何版本。
#include <iostream>
#include <type_traits>
template<typename T,int32_t N>
class MyTemplateClass
{
};
template<typename C>
void DoStuff(const C& myObj)
{
if constexpr(std::is_base_of_v<MyTemplateClass<char,64>, C>) // how do I remove the hardcoded 64?
{
// test passed!
}
else
{
static_assert(false);
}
}
int main()
{
MyTemplateClass<char, 64> passesObj;
MyTemplateClass<char, 128> shouldPassObj;
MyTemplateClass<wchar_t, 64> failsObj;
DoStuff(passesObj); // passes correctly
DoStuff(shouldPassObj); // currently fails, want to make pass
DoStuff(failsObj); // correctly fails
}
答案 0 :(得分:5)
您过于关注新的语言功能,而不是旧的技术。如果要让模板函数仅在给定类型是将MyTemplateClass
作为其第一个参数char
的{{1}}的任何实例的情况下起作用,则将其写为:
template<int32_t N>
void DoStuff(const MyTemplateClass<char, N> &myObj)
{
// test passed!
}
这是标准模板参数推导,而不是C ++ 17 if constexpr
体操。除了使用MyTemplateClass
实例化的char
模板生成的类型之外,其他任何类型都无法调用此方法。
使用模板参数包可能会有更通用的解决方案,但是由于包中的所有参数都必须属于一种模板参数(类型,值或模板),因此您将无法混合使用类型和同一包中的值模板参数:
template<typename ...Args>
void DoStuff(const SomeClass<known, params, ...Args> &myObj);
这仅在额外的参数是类型参数而不是值或模板参数的情况下才有效。您可以使用Args
使auto
成为值参数包,但是它们不能成为类型。 C ++没有机制来创建已知种类的模板参数。
答案 1 :(得分:0)
如果DoStuff()
仅收到MyTemplateClass
个对象,则可以使用模板推论
template <typename T, std::int32_t N>
void DoStuff (MyTemplateClass<T, N> const & myObj)
{
if constexpr ( std::is_same_v<char, T> )
{
// test passed!
}
else
{
// not passed
}
}
另一种解决方案是在constexpr
中添加一个MyTemplateClass
值
template <typename T, std::int32_t N>
class MyTemplateClass
{ using type = T };
template<typename C>
void DoStuff(const C& myObj)
{
if constexpr ( std::is_same_v<typename C::type, char> )
{
// test passed!
}
else
{
// not passed
}
}
第三个解决方案可能是自定义类型特征以提取N
template <typename>
struct getT;
template <typename T, std::int32_t N>
struct getT<MyTemplateClass<T, N>
{ using type = T };
template<typename C>
void DoStuff(const C& myObj)
{
if constexpr ( std::is_same_v<typename getT<C>::type, char> )
{
// test passed!
}
else
{
// not passed
}
}