模板的C ++错误和参数的推断冲突类型

时间:2014-12-07 12:06:30

标签: c++ templates makefile member-function-pointers member-functions

我在这个问题上坐了好一会儿。问题是,我想要一个可以测量函数需要终止的CPU周期和时钟时间的类。 问题是我想给这个类的成员函数Meter不同的指针来自具有不同返回类型和参数类型的函数。 (在我的案例中,Fibonacci和排序算法) 我被困了,无法继续下去。我希望你能帮助我。

Meter.h:

class Meter
{
Stopwatch w;

const char* filenameTime;
const char* filenameCycle;
const char* filenamePlotTime;
const char* filenamePlotCycle;

vector<uint64_t> t_measures;
vector<uint64_t> c_measures;

uint64_t t_max;
uint64_t t_min;
double t_mean;

uint64_t c_max;
uint64_t c_min;
double c_mean;

double t_standardDeviation;

double c_standardDeviation;

uint32_t numberOfTests;

public:

    //const char* filename;

    Meter(const char* fileData,const char* FileCycle,const char* filePlotCycle,const             char* filePlotTime);

    template<typename RT,typename PT>
    void measure(uint32_t numOfTest, RT(*f)(PT arg),PT valueToTest);

    template<typename RT,typename PT>
    void measureAlgorithmTime(uint32_t numOfTest, RT(*f)(PT arg),PT valueToTest);

    template<typename RT,typename PT>
    void measureAlgorithmCycles(uint32_t numOfTest, RT(*f)(PT arg),PT valueToTest);

    void initfileData();
    void initfileCycle();

    void printDataTime(const char* casename);
    void printDataCycle(const char* casename);
    void printDataToPlotTime(const char* casename,int n);
    void printDataToPlotCycle(const char* casename, int n);
};

template <typename RT, typename PT>
void Meter::measure(uint32_t numOfTest, RT(*f)(PT arg), PT valueToTest)
{
measureAlgorithmTime(numOfTest, (*f),valueToTest);
measureAlgorithmCycles(numOfTest, (*f), valueToTest);
}
template <typename RT, typename PT>
void Meter::measureAlgorithmTime(uint32_t numOfTest, RT(*f)(PT arg), PT valueToTest)
{

if(numOfTest > 0)numberOfTests = numOfTest;

t_measures = vector<uint64_t>(numberOfTests, 0);

//do tests
for(uint64_t i = 0; i < numberOfTests; i++)
{
    w.start();
    (*f)(valueToTest);
    w.stop();
    t_measures[i] = w.peek();
    w.reset();
}
/*
compute statistcs
 .
 .
 .
*/
template <typename RT, typename PT>
void Meter::measureAlgorithmCycles(uint32_t numOfTest, RT(*f)(PT arg), PT valueToTest)
{

if(numOfTest > 0) numberOfTests = numOfTest;

//build Memory for Data from Measurements
c_measures = vector<uint64_t>(numberOfTests, 0);



//unsigned long flags;
uint64_t c_start, c_end, c_diff;
unsigned cycles_low, cycles_high, cycles_low1, cycles_high1;
//disable preemption
//preempt_disable();
//disable hard interrupts
//raw_local_irq_save(flags);

for(uint64_t i = 0; i < numberOfTests;i++)
{

    asm volatile
    (
        "CPUID\n\t"
        "RDTSC\n\t"
        "mov %%edx,  %0\n\t"
        "mov %%eax,  %1\n\t": "=r" (cycles_high), "=r" (cycles_low):: "%rax", "%rbx",       "%rcx", "%rdx"
    );

    //call function to measure and let it do work
    (*f)(valueToTest);

    asm volatile
    (
        "CPUID\n\t"
        "RDTSC\n\t"
        "mov %%edx, %0\n\t"
        "mov %%eax, %1\n\t": "=r" (cycles_high1), "=r" (cycles_low1):: "%rax", "%rbx", "%rcx", "%rdx"
    );

主要:

#include <Meter.h>
#include <Sorting.h>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
char AlgName[20];

cout << "Start to Measure Sorting Algorithms!" <<endl;

uint32_t numberoftest = 10;
int lengthOfTestVector = 10;
vector<int> test;
test.reserve(lengthOfTestVector);
Sorting::addRandomNumbers(test);
Sorting::printOut(test);

cout << "Start to Measure InsertionSort" << endl;

Meter InsertionSort = Meter("InsertionSort_Time","InsertionSort_Cycle",
                            "InsertionSort_Plot_Cycle","InsertionSort_Plot_Time");

for(uint32_t i = 0;i < numberoftest;i++)
{
    InsertionSort.measure(numberoftest,*Sorting::insertionSort<int>,test);
    InsertionSort.printDataTime(AlgName);
    InsertionSort.printDataCycle(AlgName);
    InsertionSort.printDataToPlotCycle(AlgName,i);
    InsertionSort.printDataToPlotTime(AlgName,i);
}

cout << "finished to Measure InsertionSort" << endl;


}

我想给Meter :: measure的2个函数是:

  • uint64_t Fibonacci :: calculateNthFibonacciNumber(uint32_t n) 和
  • void Sorting :: insertionSort(vector&amp; toSort)

我用gcc和我自己的makefile编译它。

Makefile:

#makros
CXX = g++
CXXFLAGS = -std=c++0x -Wall -O -c
FLAGSFOROBJECTS = -o $@
#-I/usr/src/linux-headers-3.13.0-32/include/asm-generic
CXXFLAGS_GTEST = -I/home/maximilian/gtest-1.7.0/include
CXXFLAGS_INCLUDE = -I/home/maximilian/Documents/AlgorithmEngineering/includes
#LDFLAGS = -L/usr/lib/libgtest.a -pthread
LDFLAGS = /home/maximilian/gtest-1.7.0/lib/.libs/libgtest.a -pthread
OBJECTS = objects/
MAINS = main/

$(OBJECTS)Sorting.o: src/Sorting.cpp includes/Sorting.h
     $(CXX) $(CXXFLAGS) $(CXXFLAGS_INCLUDE) src/Sorting.cpp $(FLAGSFOROBJECTS)

$(OBJECTS)Stopwatch.o: test/Stopwatch.cpp includes/Stopwatch.h
     $(CXX) $(CXXFLAGS) $(CXXFLAGS_INCLUDE) test/Stopwatch.cpp $(FLAGSFOROBJECTS)

$(OBJECTS)Meter.o: test/Meter.cpp includes/Meter.h
     $(CXX) $(CXXFLAGS) $(CXXFLAGS_INCLUDE) test/Meter.cpp $(FLAGSFOROBJECTS)

$(OBJECTS)Sorting_meter.o: $(MAINS)Sorting_meter.cpp
     $(CXX) $(CXXFLAGS) $(CXXFLAGS_INCLUDE) $(MAINS)Sorting_meter.cpp $(FLAGSFOROBJECTS)
Sorting_meter: $(OBJECTS)Sorting_meter.o $(OBJECTS)Sorting.o $(OBJECTS)Meter.o       $(OBJECTS)Stopwatch.o
     $(CXX) -o Sorting_meter $(OBJECTS)Sorting_meter.o $(OBJECTS)Sorting.o $(OBJECTS)Meter.o $(OBJECTS)Stopwatch.o $(LDFLAGS)

错误是:

g++ -std=c++0x -Wall -O -c -I/home/maximilian/Documents/AlgorithmEngineering/includes    main/Sorting_meter.cpp -o objects/Sorting_meter.o
main/Sorting_meter.cpp: In function ‘int main()’:
main/Sorting_meter.cpp:26:77: error: no matching function for call to       ‘Meter::measure(uint32_t&, void (&)(std::vector<int>&), std::vector<int>&)’
     InsertionSort.measure(numberoftest,*Sorting::insertionSort<int>,test);
                                                                         ^
main/Sorting_meter.cpp:26:77: note: candidate is:
In file included from main/Sorting_meter.cpp:1:0:
/home/maximilian/Documents/AlgorithmEngineering/includes/Meter.h:55:14: note:      template<class RT, class PT> void Meter::measure(uint32_t, RT (*)(PT), PT)
     void measure(uint32_t numOfTest, RT(*f)(PT arg),PT valueToTest);
          ^
/home/maximilian/Documents/AlgorithmEngineering/includes/Meter.h:55:14: note:   template      argument deduction/substitution failed:
main/Sorting_meter.cpp:26:77: note:   deduced conflicting types for parameter ‘PT’      (‘std::vector<int>&’ and ‘std::vector<int>’)
     InsertionSort.measure(numberoftest,*Sorting::insertionSort<int>,test);
                                                                         ^
make: *** [objects/Sorting_meter.o] Error 1

我尝试了一切以避免错误,但现在我不知道,我希望你能帮助我。

提前致谢!

1 个答案:

答案 0 :(得分:2)

template <typename RT, typename PT>
void Meter::measure(uint32_t numOfTest, RT(*f)(PT arg), PT valueToTest)
{
    // […]
}

PT是从第二个和第三个参数推断出来的。在main我们有

InsertionSort.measure(numberoftest, *Sorting::insertionSort<int>, test);

分别注意第二个和第三个参数的类型:

  • test会导致PT被推断为vector<int>

  • 我们看不到Sorting::insertionSort的声明,但我认为它以vector<T>&为参数。因此,PT将被推断为vector<int>&,这不是我们之前的推论所产生的。 (星号可能是不必要的,因为它会自动将专门化衰减到函数指针并随后取消引用它)

通过使第三个参数成为非推导的上下文或使用第二个模板参数来解决这个问题。 E.g。

template <typename RT, typename PT, typename PT2>
void Meter::measure(uint32_t numOfTest, RT(*f)(PT arg), PT2 const& valueToTest)
{
    measureAlgorithmTime(numOfTest, (*f),valueToTest);
    measureAlgorithmCycles(numOfTest, (*f), valueToTest);
}