1

我有一个由一组类模板显式特化提供支持的函数模板,其语法如下

abc.GetAs<DesiredType>("Name");

(在哪里GetAs<t>是这样的:

template<typename T>
T GetAs(wchar_t const* propName) const
{
    typedef Converter<T> Converter;
    auto thing = Get(propName);
    return Converter::Convert(thing);
}

)

当该类型是枚举时,我想有一个专门DesiredType化,以便返回的类型与枚举的基础类型(或enum class)匹配。

这是可能的还是客户只​​需要自己指定基础类型?


我试图允许这样的代码:

enum class Example
{
    One,
    Two
}

int main()
{
    foo_ipc_class ic(L"/// Construct me");
    // Today, calls the primary template rather than an explicit
    // specialization for an integral type.
    Example ex = ic.GetAs<Example>(L"Property Name");
}
4

2 回答 2

2

由于不可能部分专门化函数模板,因此您必须更改您的实现以使用“委托到类”技巧:

#include <type_traits>

// Class to delegate to
template <typename T, bool isEnum = std::is_enum<T>::value>
struct GetAs_Class {
  typedef your_return_type ReturnType;
  static ReturnType GetAs(your_parameters) { your_code; }
};

// Partial specialisation    
template <typename T>
struct GetAs_Class<T, true> {
  typedef specialisation_return_type ReturnType;
  static ReturnType GetAs(your_parameters) { specialisation_code; }
};


// Your function now delegates to the class
template <typename T>
typename GetAs_Class<T>::ReturnType GetAs(your_parameters) {
  return GetAs_Class<T>::GetAs(your_arguments);
}
于 2013-05-20T14:18:36.290 回答
1

您可以使用 SFINAE 根据模板参数是否为枚举来启用/禁用重载。std::is_enumstd::underlying_type派上用场。为简单起见,我将其编写GetAs为免费函数:

#include <type_traits>
#include <iostream>

template<typename T>
struct identity {
    typedef T type;
};

template<typename T>
typename std::enable_if<!std::is_enum<T>::value, identity<T>>::type::type
GetAs(wchar_t const*)
{
    std::cout << "general\n";
    // return something
}

template<typename T>
typename std::enable_if<std::is_enum<T>::value, std::underlying_type<T>>::type::type
GetAs(wchar_t const*)
{
    std::cout << "enum\n";
    // return something
}

enum class E : short {
};

int main()
{
    GetAs<int>(L"hm");
    GetAs<E>(L"hm");
}

它非常难看,但是委托给一个类来模仿函数模板的部分专业化也是如此,IMO :)

于 2013-05-20T14:42:01.440 回答