簡體   English   中英

調用非模板化類c ++的模板化函數時出錯

[英]Error calling templated function of non-templated class c++

我在非模板化的類中有一個模板化的函數,如下所示:

class Foo
{
  public:
  template <class T>
  void func(T& val)
  {
     //do work here
  }
}

然后,在main.cpp中我正在做:

Foo a;
std::string val;
a.func<std::string>(val);  //this line gives the error

我收到一條錯誤,說“在'>'之前預期的主表達式” 所以我快速搜索谷歌,發現每個人都建議一個簡單的解決方案:

a.template func<std::string>(val);

唯一的問題是,我仍然得到完全相同的錯誤。

編輯:

我沒有提供完整示例的原因是因為它涉及外部庫和冗長的代碼,這些代碼模糊了問題,但由於上面的簡化代碼沒有削減它。 這是我寫的完整課程:

class ConfigFileReader
{
public:
    ConfigFileReader() { }

    ConfigFileReader(const std::string& config_file_path)
    {
      setConfigFilePath(config_file_path);
    }

    ~ConfigFileReader() { }

    void setConfigFilePath(const std::string& config_file_path)
    {
    try
    {
        root_node_ = YAML::LoadFile(config_file_path);
    }
    catch(const YAML::BadFile& file_load_exception)
    {
        printf("Error opening YAML file. Maybe the file path is incorrect\n%s", file_load_exception.msg.c_str());
    }

    }

    template<class T>
    bool getParam(const std::string& param_key, T& param_value)
    {
        if (root_node_.IsNull() || !root_node_.IsDefined())
        {
            printf("Root node is undefined or not set");
            return false;
        }

        YAML::Node node = YAML::Clone(root_node_);

        std::vector<std::string> split_name;
        boost::split(split_name, param_key, boost::is_any_of("/"));

        for(const std::string& str: split_name)
        {
            if (!node.IsMap())
            {
                std::cout << "Parameter was not found (Node is null)." << str << std::endl;   //replace with printf
                return false;
            }

            node = node[str];
        }

        if (node.IsNull() || !node.IsDefined())
        {
            std::cout << "Parameter was not found (Node is null/undefined)." << std::endl;
            return false;
        }

        try
        {
            param_value = node.as<T>();
            return true;
        }
        catch (const YAML::TypedBadConversion<T>& type_conversion_exception)
        {
            std::cout << "Error converting param value into specified data type" << std::endl;
            std::cout << type_conversion_exception.msg << std::endl;
        }

        return false;
    }

private:
    YAML::Node root_node_;
};

然后,在一個單獨的cpp文件中是main函數

int main(int argc, char** argv)
{
if (argc != 2)
{
  printf("Incorrect number of arguments given");
    return EXIT_FAILURE;
}

printf("Config file path: %s", argv[1]);

ConfigFileReader config_file_reader(std::string(argv[1]));

std::string param_out;

bool success = config_file_reader.template getParam<std::string>("controller/filepath", param_out);  //<-- ERROR HERE

return EXIT_SUCCESS;
}

編譯器: gcc 4.8.4,編譯時設置c ++ 11標志。

編輯2:在代碼中添加了字符串參數構造函數。

你的問題是:

ConfigFileReader config_file_reader(std::string(argv[1]));

被解釋為名為config_file_reader的函數的前向聲明,該函數接受指向字符串的指針。 請參閱錯誤消息:

ConfigFileReader(std :: __ cxx11 :: string *){aka ConfigFileReader(std :: __ cxx11 :: basic_string *)}'

這是因為你遇到了最令人煩惱的解析

使用ConfigFileReader config_file_reader(std::string{argv[1]}); 為編譯器更好地消除歧義,您打算構造一個對象。 然后編譯器會開始抱怨你錯過了一個接受字符串的構造函數!

有一個默認的構造函數,所以當我們使用:

ConfigFileReader config_file_reader;

它沒有問題。

所以:

  1. 然后為ConfigFileReader定義一個接受string的構造函數
  2. 以這樣的方式調用它,使代碼明確無誤

演示

它甚至更簡單:

Foo a;
std::string val;
a.func(val);  // The compiler assumes T = std::string

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM