VS2015 C++ : unable to match function definition t

2019-08-11 00:34发布

I try to make NCORR library work on VS2015 C++. The library was originally written on Linux.

As part of the library there is code similar to

#include <chrono>

template<typename T_container>
struct container_traits {
    typedef typename T_container::container              nonconst_container;
};


template <typename T_container>
class base_region {
public:

    typedef typename container_traits<T_container>::nonconst_container nonconst_container;

    template<typename T_container2>
    typename std::enable_if<std::is_same<typename container_traits<T_container2>::nonconst_container, typename nonconst_container>::value, base_region&>::type operator=(const base_region<T_container2>&);
};

template <typename T_container>
template <typename T_container2>
typename std::enable_if<std::is_same<typename container_traits<T_container2>::nonconst_container, typename base_region<T_container>::nonconst_container>::value, base_region<T_container>&>::type base_region<T_container>::operator=(const base_region<T_container2>& reg) {
    return *this;
}


int main()
{
    return 0;
}

When I try to compile the code on VS2015 win32 console application, I get

C2244   'base_region<T_container>::operator =': unable to match function definition to an existing declaration  ConsoleApplication5

I think the problem is typename nonconst_container in declaration vs typename base_region<T_container>::nonconst_container in definition.

Do you know what is wrong and how can I make the code work?

1条回答
你好瞎i
2楼-- · 2019-08-11 01:06

First, typename nonconst_container is ill-formed. typename is only allowed before a qualified name.

MSVC seems to have problems matching nonconst_container in the class template definition and the typename base_region<T_container>::nonconst_container in the out-of-class member function definition.

A workaround (which is also shorter) is to use a trailing-return-type:

template <typename T_container>
template <typename T_container2>
auto base_region<T_container>::operator=(const base_region<T_container2>& reg)
  -> typename std::enable_if<std::is_same<typename container_traits<T_container2>::nonconst_container,
                                          nonconst_container>::value, base_region&>::type 
                                       // ^^^^^^^^^^^^^^^^^^          ^^^^^^^^^^^
{
   //...
}

Everything after base_region<T_container>::operator= gets looked up just like a name used in the member function body (in particular, it will first look at class members), so you can just write nonconst_container and base_region&, and happily sidestep the MSVC bug.

查看更多
登录 后发表回答