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

标签 c++ templates makefile pointer-to-member member-functions

我在这个问题上坐了很长时间。问题是,我想要一个可以测量函数终止所需的 CPU 周期和时钟时间的类。 问题是我想为此类 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::计算 NthFibonacciNumber(uint32_t n) 和
  • void Sorting::insertionSort(vector &toSort)

我用 gcc 和我自己的 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

我已尽一切努力避免错误,但现在我不知道,我希望你能帮助我。

提前致谢!

最佳答案

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>& ,这不是我们之前推论的结果。 (星号可能是不必要的,因为它会自动衰减对函数指针的特化并随后取消引用它)

通过将第三个参数设为非推导上下文或使用第二个模板参数来解决该问题。例如

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);
}

关于模板的 C++ 错误和推导的参数冲突类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27342427/

相关文章:

c++ - __uint128_t 不适用于 Clang 和 libstdc++

c++ - 在cocos2dx中听不到音效

c++ - 如何将模板的实例传递给另一个模板的另一个实例?

c++ - 如何使用模板参数编写外联构造函数?

c++ - 基于运算符推导模板返回类型? : result

c - 未使用 gcc 和 makefile 为 #ifdef 定义值

c++ - Github 通过克隆获得必要的库

django - 包含标记错误.....指定的模板库无效。尝试加载时引发 ImportError

c - MakeFile 创建

c++ - 目标 'Project1.exe' 的配方失败