I would like to write a general function to search in different containers. Cointainers contain shared pointers to different types. At the moment I have this
template<typename TInstance, typename THandle, typename TContainer>
auto FindInContainer(TContainer& container, THandle handle) -> decltype(boost::shared_ptr<TInstance>())
{
std::lock_guard<std::mutex> lock(_mutex);
const auto& found = std::find_if(container.begin(), container.end(),
[handle](typename TContainer::value_type& instance)
{
return instance.get() == reinterpret_cast<typename TContainer::value_type::element_type*>(handle.handle);
});
if (found == container.end())
return boost::shared_ptr<TInstance>();
return *found;
}
I use MSVC 2015 Update 1, but somehow it cannot figure out the TInstance type, even though I used the return type specified (whatever the term for the thing for the -> operator in the method signature).
return FindInContainer<SensorController>(_sensors, handle); // Works
return FindInContainer(_sensors, handle); // Does not compile
The _sensors is defined as
std::vector<boost::shared_ptr<SensorController>> _sensors;
Is my C++ is rusty, or the compiler does not support this type deduction?
A template argument cannot be deduced from the return type of a function template. Only parameters of the function template participate in template argument deduction. Since TInstance
does not figure in any of the parameters of FindInContainer
, it cannot be deduced.
If VS 2015 Update 1 supports it, you could use return type deduction (a C++14 feature) for the function template (omit the return type altogether):
template<typename THandle, typename TContainer>
auto FindInContainer(TContainer& container, THandle handle)
{
// ... as before
}
If that's not supported, you can resort to extracting the type from the container (as you're already doing):
template<typename THandle, typename TContainer>
typename TContainer::value_type FindInContainer(/*...*/)
{
// ... as before
}