0

这是我想做的伪代码。

template<typename T>
struct ConvertToT
{
    static_assert(false, "Explicit specialization for T required.");

    // Variant will be coerced to this type before calling Convert.
    std::uint32_t GetVariantType()
    {
        return VT_EMPTY;
    }
    T Convert(CComVariant& input)
    {
        return "ERROR!";
    }
};

template<>
struct ConvertToT<std::wstring>
{
    std::uint32_t GetVariantType()
    {
        return VT_BSTR;
    }
    T Convert(CComVariant& input)
    {
        return std::wstring(input.bstrVal, ::SysStringLen(input.bstrVal));
    }
};

/* repeat for several more explicit specializations:
 * template<>
 * struct ConvertToT<...>
 * {
 *     std::uint32_t GetVariantType()
 *     {
 *         return ...;
 *     }
 *     ... Convert(CComVariant& input)
 *     {
 *         return ...;
 *     }
 * };
 */

有什么方法可以禁用主模板并需要使用明确的专业化?

4

3 回答 3

6

是的,只是不要定义主模板:

template <typename> struct ConvertToT;

template <> struct ConvertToT<int>
{
    // ...
};

// etc.

如果你喜欢静态断言,你可以得到可编译的代码,你猜对了,一个额外的间接级别:

template <typename> struct never_true : std::false_type { };

template <typename T> struct Foo
{
    static_assert(never_true<T>::value, "Can't use this.");
};

这适用于完整类型和不完整类型。

(您也可以使用!std::is_same<T, T>::value。)

于 2013-04-29T19:08:29.120 回答
3

最简单的方法就是不提供实现。就像是:

template <typename T>
struct ConvertToT;

template<>
struct ConvertToT<SomeType>
{
    //  ...
};

等等。

于 2013-04-29T19:09:34.813 回答
0

您可以保留最初的方法,但使用 Boost 增强它:

http://www.boost.org/doc/libs/1_36_0/libs/type_traits/doc/html/boost_typetraits/reference/is_class.html

template<typename T>
struct ConvertToT
{
    BOOST_STATIC_ASSERT_MSG(
    (boost::is_class<std::wstring, T>::value),
    "T must be of wstring type"
     );

    // Variant will be coerced to this type before calling Convert.
    std::uint32_t GetVariantType()
    {
        return VT_EMPTY;
    }
    T Convert(CComVariant& input)
    {
    return "ERROR!";
   }
};

或者,如果您使用 C++11,请使用 std::is_class。

于 2013-04-29T19:22:09.300 回答