How can I force a client to call an explicitly specialized template instead of the primary template?

不想你离开。 提交于 2019-12-11 20:37:52

问题


This is pseudocode for what I want to do.

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 ...;
 *     }
 * };
 */

Is there some way I can disable the primary template and require use of an explicit specialization?


回答1:


Yes, just don't define the primary template:

template <typename> struct ConvertToT;

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

// etc.

If you like a static assertion, you can get compilable code with, you guessed it, one extra level of indirection:

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

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

This works for both complete and incomplete types.

(You can also use !std::is_same<T, T>::value.)




回答2:


The easiest way is just to not provide an implementation. Something like:

template <typename T>
struct ConvertToT;

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

and so on.




回答3:


You can leave your initial approach but enhace it with 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!";
   }
};

Or if you are using C++11 use std::is_class.



来源:https://stackoverflow.com/questions/16286303/how-can-i-force-a-client-to-call-an-explicitly-specialized-template-instead-of-t

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!