1

如果我有一个有两个模板参数的类,有没有办法只在其中一个参数上分支 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
}
4

2 回答 2

5

你太专注于新的语言特性而不是旧的技术。如果您想要一个模板函数,该函数仅在给定类型是MyTemplateClass其第一个参数的任何实例时才有效char,请编写:

template<int32_t N>
void DoStuff(const MyTemplateClass<char, N> &myObj)
{
  // test passed!
}

这是标准模板参数推导,而不是 C++17if constexpr体操。除了从MyTemplateClasschar.

可以使用模板参数包获得更通用的解决方案,但由于包中的所有参数都必须属于一种模板参数(类型、值或模板),因此您将无法混合使用类型和值模板参数在同一个包中:

template<typename ...Args>
void DoStuff(const SomeClass<known, params, ...Args> &myObj);

只有当额外的参数是类型参数,而不是值或模板参数时,这才有效。您可以使用 制作Args值参数包auto,但它们不能是类型。C++ 没有机制来生成已知类型的模板参数。

于 2019-12-12T15:40:39.393 回答
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
    }
}

另一种解决方案可能是constexprMyTemplateClass

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
    }
}
于 2019-12-12T15:46:33.057 回答