【问题标题】:Compiler warning for Template case, that should be covered by Template Specialization模板案例的编译器警告,应包含在模板专业化中
【发布时间】:2014-10-25 12:30:57
【问题描述】:

在我用 C++98 编码期间,我收到一个奇怪的编译器警告,我不明白:( 请参阅:

我有一个文件 TemplateSpecialization.hpp:

namespace TemplateNamespace
{
    template <typename T> T getParam(int param)
    {
        return static_cast<T>(param);
    }
}

struct A
{
    A () : aaa(10) {}
    int aaa;
    template <typename T> T getAaa()
    {
        return TemplateNamespace::getParam<T>(aaa);
    }
};

还有一个文件TemplateSpecialization.cpp:

#include "TemplateSpecialization.hpp"
#include <string>
#include <sstream>

namespace TemplateNamespace {
    template<> std::string getParam<std::string>(int param)
    {
        std::stringstream ss;
        ss << param;
        return ss.str();
    }
}

当我在其他 .CPP 文件中的任何位置调用此函数时,例如Test.cpp by

A a; std::string s = a.getAaa<std::string>();

并使用 gcc 版本 4.8.2 编译所有内容我收到此警告:

In file included from /var/fpwork/sokeks/Test.cpp:22:0:
    /var/fpwork/sokeks/TemplateSpecialization.hpp: In instantiation of 'T TemplateNamespace::getParam(int) [with T = std::basic_string<char>]':
    /var/fpwork/sokeks/TemplateSpecialization.hpp:15:50:   required from 'T A::getAaa() [with T = std::basic_string<char>]'
    /var/fpwork/sokeks/Test.cpp:161:43:   required from here
    /var/fpwork/sokeks/TemplateSpecialization.hpp:5:36: warning: invalid conversion from 'int' to 'const char*' [-fpermissive]
             return static_cast<T>(param);
                                    ^

我完全不明白,是什么导致了这个警告!为什么编译器会指出专门的模板函数!?它到底是什么意思?我确实使用 std::string,而不是 const char*。

提前谢谢帮助!

【问题讨论】:

  • 你的专精没有被选中。专门化函数模板是个坏主意。改用重载。 gotw.ca/publications/mill17.htm
  • 好的,谢谢,我会读一读!
  • @pmr sokek 如何在返回类型上超载?
  • @Yakk 啊,那当然行不通。对不起,错误的建议。不过这个建议仍然有效。
  • @pmr 它可以——采用一个反向转换的虚拟标签类型,或者返回一个帮助对象,但两者都是不平凡的解决方案。

标签: c++ templates compiler-warnings template-specialization c++98


【解决方案1】:

这是一个可见性问题:特化是在另一个编译单元中,当需要实例化模板时它是不可见的。将模板和声明放入头文件,将完全专用函数的定义放入 cpp 文件并使用一些包含保护:

TemplateSpecialization.hpp

#pragma once

#include <string>
#include <sstream>

namespace TemplateNamespace
{
    template <typename T> T getParam(int param)
    {
        return static_cast<T>(param);
    }

    template<> std::string getParam<std::string>(int param);
}

struct A
{
    A() : aaa(10) {}
    int aaa;
    template <typename T> T getAaa()
    {
        return TemplateNamespace::getParam<T>(aaa);
    }
};

TemplateSpecialization.cpp

#include "TemplateSpecialization.hpp"

template<> std::string TemplateNamespace::getParam<std::string>(int param)
{
    std::stringstream ss;
    ss << param;
    return ss.str();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 2014-07-06
    • 2010-12-26
    • 1970-01-01
    相关资源
    最近更新 更多