我正在尝试在某些结构上对stl算法进行基准测试:
using namespace std;
template<typename A, typename T>
void test(){
T c(1000);
A(c.begin(), c.end(), true);
}
int main(){
test<find,vector<bool>>();
}
但我得到template argument deduction/substitution failed
答案 0 :(得分:3)
编译错误本身在其他答案中得到了很好的讨论。我提出了一个使用C ++ 14通用lambdas的解决方案:
template<typename Container, typename Algorithm>
void test(Algorithm algo = Algorithm()){
Container c(1000);
algo(c.begin(), c.end(), true);
}
int main(){
auto find_proxy = [](auto ... args){ return std::find(args...); };
test<std::vector<bool>>(find_proxy);
}
答案 1 :(得分:1)
每个人的回答都很好,但是让我再补充一点。
让代码正常工作而不会发生太大变化..这就是必须要发生的事情。
#include <vector>
#include <algorithm>
template< typename SearchFunctionType, typename ContainerType >
void test( SearchFunctionType fSearch, const ContainerType& container){
fSearch(container.begin(), container.end(), true);
}
int main(){
std::vector<bool> v(1000);
test(std::find<std::vector<bool>::const_iterator, bool>, v);
}
std :: find不是每个人都指出的类型。 std :: find是一个函数。您可以将其作为函数指针传递。然后看,std :: find又是模板函数,编译器也不知道std :: find会有哪些模板参数。这就是为什么你不只是传递std :: find。相反,
std::find<std::vector<bool>::const_iterator, bool>.
编辑:
#include <algorithm>
#include <vector>
template < typename ContainerType
, typename ContainerType::const_iterator (*fpSearchFunction) (typename ContainerType::const_iterator, typename ContainerType::const_iterator, const typename ContainerType::value_type&) >
void test(const ContainerType& c, const typename ContainerType::value_type& value)
{
fpSearchFunction(c.begin(), c.end(), value);
}
int main()
{
std::vector<bool> v(1000);
test< std::vector<bool>, std::find<std::vector<bool>::const_iterator, bool> >(v, true);
}
这适用于VisualC。是。整数类型或函数指针也可以是模板参数。我打赌有比这更好的方法。
编辑2:
虽然我不明白为什么把它加以寺庙化比仅仅硬编码更好,但如果我确实做了一些复杂的话,我就会这样做。
#include <vector>
#include <algorithm>
#include <chrono>
#include <iostream>
#include <cstdlib>
#include <functional>
template <typename ContainerType>
class Benchmark
{
public:
typedef typename ContainerType::const_iterator ConstIteratorType;
typedef typename ContainerType::value_type ValueType;
typedef std::function < ConstIteratorType(ConstIteratorType, ConstIteratorType, const ValueType&) >
SearchFunctionType;
typedef std::chrono::high_resolution_clock ClockType;
void TestAll(const ContainerType& container, const ValueType& serachVal)
{
for (std::size_t i = 0; i < m_functions.size(); ++i)
{
ClockType::time_point begin = ClockType::now();
m_functions[i](container.begin(), container.end(), serachVal);
ClockType::duration duration = ClockType::now() - begin;
std::cout << i << " : " << duration.count() << std::endl;
}
}
void PushBack(SearchFunctionType fSearch)
{
m_functions.push_back(fSearch);
}
private:
std::vector<SearchFunctionType> m_functions;
};
int main(){
typedef Benchmark<std::vector<bool>> BenchmarkType;
BenchmarkType benchmark;
benchmark.PushBack(std::find<BenchmarkType::ConstIteratorType, BenchmarkType::ValueType>);
benchmark.PushBack([](BenchmarkType::ConstIteratorType begin, BenchmarkType::ConstIteratorType end, const BenchmarkType::ValueType& v)
{
BenchmarkType::ConstIteratorType iter;
do
{
iter = begin + std::rand() % (end - begin);
if (*iter == v)
return iter;
} while (iter != end);
return end;
});
struct BinarySearch
{
BenchmarkType::ConstIteratorType operator()(BenchmarkType::ConstIteratorType begin, BenchmarkType::ConstIteratorType end, const BenchmarkType::ValueType& v)
{
return std::lower_bound(begin, end, v);
}
};
benchmark.PushBack(BinarySearch());
std::vector<bool> c;
c.assign(10000, false);
c.back() = true;
benchmark.TestAll(c, true);
}
输出:
0 : 100005
1 : 300017
2 : 0
答案 2 :(得分:0)
问题是你试图将模板作为模板参数传递,并希望它被推断 - 这不会起作用,因为编译器必须在某个时刻开始填充类型:{{1 }}不是std::find
,但你需要它是一个!
答案 3 :(得分:0)
非常正确。 valgrind
需要类型名称。 typename A
不是一种类型。您可能希望将std::find
作为常规参数传递,然后传递A a
的实例化。
答案 4 :(得分:0)
好像你想传递一个要在function addSelectBox(){
var parentDiv = document.getElementById ("main");
var selectElement = '<select>';
for (var i=0;i < 6000;i++) {
selectElement+= '<option value="'+i+'">---- ' + i+'</option>';
}
selectElement += '</select>';
parentDiv.innerHTML+=selectElement;
}
的实例上执行的函数?但是您不能使用函数模板来替换预处理器。
T
是算法的名称,而不是类型名称。您需要定义要用作find
的真实类型,也许是A
在其参数上执行operator()
的仿函数。
建议您首先使用std::find
使逻辑工作,然后提取A
作为模板参数。增量方法通常有助于构建复杂的类或函数模板,并且通常,但是破坏的模板代码的编译器错误可能尤其令人困惑。
答案 5 :(得分:0)
您应该检查它在C ++库中的完成情况:
template< class InputIt, class UnaryPredicate >
typename iterator_traits<InputIt>::difference_type
count_if( InputIt first, InputIt last, UnaryPredicate p );
如您所见,您必须将functor类型作为模板参数和functor实例作为函数参数提供。