为什么NVCC无法将函数定义与现有声明匹配?

时间:2018-04-19 14:14:45

标签: cuda

我有这些文件在使用nvcc

进行编译时会产生以下错误
error C2244: 'TemplateClass<N>::print': unable to match function definition to an existing declaration 
note: see declaration of 'TemplateClass<N>::print' 
note: definition note: 'void TemplateClass<N>::print(const std::string [])' 
note: existing declarations note: 'void TemplateClass<N>::print(const std::string [N])'

Template.h

#pragma once

#include <string>
#include <iostream>

template <unsigned int N>
class TemplateClass
{
private:
    std::string name;

public:
    TemplateClass();
    TemplateClass(const std::string& name);
    void print(const std::string familyName[N]);
};

#include "template.inl"

Template.inl

template <unsigned int N>
TemplateClass<N>::TemplateClass()
{
    name = "Unknown";
}

template <unsigned int N>
TemplateClass<N>::TemplateClass(const std::string& name)
{
    this->name = name;
}

template <unsigned int N>
void TemplateClass<N>::print(const std::string familyName[N])
{
    std::cout << "My name is " << name << " ";
    for (auto i = 0; i < N; i++)
        std::cout << familyName[i] << " ";
    std::cout << std::endl;
}

consume_template.cu

#include "template.h"

void consume_template_gpu()
{
    TemplateClass<3> obj("aname");
    std::string namesf[3];
    namesf[0] = "un";
    namesf[1] = "deux";
    namesf[2] = "trois";
    obj.print(namesf);
}

我使用的是VS2017 15.4.5,后来的版本无法用CMake创建项目。

该项目是使用CMake创建的

cmake_minimum_required(VERSION 3.10)

project(template_inl_file LANGUAGES CXX CUDA)

set (lib_files template.h consume_template.cu)
add_library(template_inl_file_lib ${lib_files})

2 个答案:

答案 0 :(得分:0)

出于好奇,尝试使用std :: string namesf = {&#34; un&#34;,&#34; deux&#34;,&#34; trois&#34;};这似乎是一个编译器问题。尝试不同的格式可能有助于编译器更好地理解。否则代码似乎没问题。 也许你错过了与CMake的一些联系。另外,尝试通过创建CUDA项目直接从VS2017进行编译而不使用CMake。

答案 1 :(得分:0)

发生的事情是数组在衰减到指针并且在编译期间数组的大小丢失。所以这个

template <unsigned int N>
void TemplateClass<N>::print(const std::string familyName[N]);

实际上会变成这个

template <unsigned int N>
void TemplateClass<N>::print(const std::string* familyName);

正如我们所看到的,编译器无法知道它必须根据数组的大小(即模板参数N)生成不同的函数。

要解决这个问题,我们可以使用旧技巧来避免像这样的数组衰减

template <unsigned int N>
void TemplateClass<N>::print(const std::string (&familyName)[N]);

现在通过编译存在大小N,编译器知道要生成不同的函数。我想,正如问题的评论中指出的那样,NVCC会产生VS本身不产生的代码,然后它不知道如何处理它。

有关以下链接主题的更多信息

http://pointer-overloading.blogspot.ch/2013/09/c-template-argument-deduction-to-deduce.html

http://en.cppreference.com/w/cpp/language/template_argument_deduction

https://theotherbranch.wordpress.com/2011/08/24/template-parameter-deduction-from-array-dimensions/