在这种情况下如何正确使用std :: enable_if

时间:2014-02-16 12:47:24

标签: c++ c++11 sfinae

我定义了以下方法:

template <typename Interface>
Interface Create();

有了这个实现:

template <typename Interface>
typename std::enable_if<std::is_pointer<Interface>::value, Interface>::type Create()
{
...
}

但现在我收到以下错误:“对ITestInterface的未定义引用* Create()”

当我删除std::enable_if时,一切正常。但我要求它工作,因为我想添加此功能的版本,当Interface是引用或Interface是std::vector时。我在这做错了什么?我也注意到这是一个链接器错误 - 但我不知道为什么。有人可以给我一个暗示吗?

1 个答案:

答案 0 :(得分:3)

在正常功能中,返回类型不是签名的一部分, 返回类型是模板功能签名的一部分 所以

template <typename Interface> Interface Create();

不同
template <typename Interface>
typename std::enable_if<std::is_pointer<Interface>::value, Interface>::type
Create();

您必须在声明和定义中使用相同的签名。

由于函数无法实现部分特化,因此必须使用辅助类: 可能会有所帮助:

namespace detail
{

template <typename > struct CreateHelper;

template <typename T> struct CreateHelper<T*>
{
    static T* create() {
        // Implementation with T*
    }
};

template <typename T> struct CreateHelper<T&>
{
    static T& create() {
        // Implementation with T&
    }
};

template <typename T> struct CreateHelper<std::vector<T>>
{
    static std::vector<T> create() {
        // Implementation with std::vector<T>
    }
};

} // namespace detail


template <typename Interface> Interface Create()
{
    return detail::CreateHelper<Interface>::create();
}