Issue with friend template functions clang++ / msvc++ and enable_if

 ̄綄美尐妖づ 提交于 2019-12-06 10:48:11

Template friends are notoriously complicated. I don't know for sure whether Clang is right, but it could be that your SFINAE trick inside the function template arguments runs afoul of

14.5.4 Friends [temp.friend]

9 When a friend declaration refers to a specialization of a function template, the function parameter declarations shall not include default arguments, nor shall the inline specifier be used in such a declaration.

C++11 introduced default template arguments for function templates, and it could be that clang interprets the above differently as g++/MSVC. It is fixable by doing SFINAE on the return type instead:

#include<type_traits>

template<typename T> class Wrap;

template<typename T>
using WrapRet = typename std::enable_if<std::is_class<T>::value, Wrap<T>>::type;

template<typename T>
WrapRet<T> make_wrapper( T i )
{
    return Wrap<T>( i );
}

template<typename T>
class Wrap : T
{
    friend WrapRet<T> make_wrapper<T>( T );
private:
    Wrap( T v ) : T( v ) {}
};

template<typename T>
class Imp
{
    T x;
public:
    Imp( T v ) {}
};

int main()
{
    auto wrap = make_wrapper( Imp<int>( 1 ) );
    return 0;
}

Live Example that works with both clang and g++.

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