考虑以下代码和apply
函数:
// Include
#include <iostream>
#include <array>
#include <type_traits>
#include <sstream>
#include <string>
#include <cmath>
#include <algorithm>
// Just a small class to illustrate my question
template <typename Type, unsigned int Size>
class Array
{
// Class body (forget that, this is just for the example)
public:
template <class... Args> Array(const Args&... args) : _data({{args...}}) {;}
inline Type& operator[](unsigned int i) {return _data[i];}
inline const Type& operator[](unsigned int i) const {return _data[i];}
inline std::string str()
{
std::ostringstream oss;
for (unsigned int i = 0; i < Size; ++i)
oss<<((*this)[i])<<" ";
return oss.str();
}
protected:
std::array<Type, Size> _data;
// Apply declaration
public:
template <typename Return,
typename SameType,
class... Args,
class = typename std::enable_if<std::is_same<typename std::decay<SameType>::type, Type>::value>::type>
inline Array<Return, Size> apply(Return (*f)(SameType&&, Args&&...), const Array<Args, Size>&... args) const;
};
// Apply definition
template <typename Type, unsigned int Size>
template <typename Return, typename SameType, class... Args, class>
inline Array<Return, Size> Array<Type, Size>::
apply(Return (*f)(SameType&&, Args&&...), const Array<Args, Size>&... args) const
{
Array<Return, Size> result;
for (unsigned int i = 0; i < Size; ++i) {
result[i] = f((*this)[i], args[i]...);
}
return result;
}
// Example
int main(int argc, char *argv[])
{
Array<int, 3> x(1, 2, 3);
std::cout<<x.str()<<std::endl;
std::cout<<x.apply(std::sin).str()<<std::endl;
return 0;
}
编译失败:
universalref.cpp: In function ‘int main(int, char**)’:
universalref.cpp:45:32: erreur: no matching function for call to ‘Array<int, 3u>::apply(<unresolved overloaded function type>)’
universalref.cpp:45:32: note: candidate is:
universalref.cpp:24:200: note: template<class Return, class SameType, class ... Args, class> Array<Return, Size> Array::apply(Return (*)(SameType&&, Args&& ...), const Array<Args, Size>& ...) const [with Return = Return; SameType = SameType; Args = {Args ...}; <template-parameter-2-4> = <template-parameter-1-4>; Type = int; unsigned int Size = 3u]
universalref.cpp:24:200: note: template argument deduction/substitution failed:
universalref.cpp:45:32: note: mismatched types ‘SameType&&’ and ‘long double’
universalref.cpp:45:32: note: mismatched types ‘SameType&&’ and ‘float’
universalref.cpp:45:32: note: mismatched types ‘SameType&&’ and ‘double’
universalref.cpp:45:32: note: couldn't deduce template parameter ‘Return’
我不太确定它为什么会失败。在该代码中,我想:
- 保持通用引用具有最通用的功能
- 能够使用语法
apply(std::sin)
那么我必须改变什么才能使其编译?