GCC中的模板没有看到在它之后声明的函数,但在实例化之前 [英] Template in GCC doesn't see a function declared after it, but before instantiation

查看:106
本文介绍了GCC中的模板没有看到在它之后声明的函数,但在实例化之前的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是Visual Studio编译好的内容:

  #include< string> 
#include< vector>

模板< typename T>
T read()
{
T值;
read(value); // gcc在这里编译错误
返回值;
}

void read(std :: string& str)
{
}

模板< typename T>
void read(std :: vector< T> vec)
{
}

int main(int argc,char ** argv){

读取< std :: string>();
读取< std :: vector< int>>();
读< std :: vector< float>>();

返回0;
}

但GCC会产生编译错误: p>

我发现了唯一对我有效的解决方案,在read()之前声明模板函数read(T&):

  template< typename T> 
void read(T&);

模板< typename T>
T read()
{
T值;
read(value);
返回值;
}

模板<>
void read(std :: string& str)
{
}

// template< typename T>
// void read(std :: vector< T> vec)
// {
//}

但我无法弄清楚如何适应模板函数。



有没有更好的方法来制作gcc看到在模板使用它们之后声明的函数,但是在模板实例化之前?为了允许以后覆盖(没有转发),你可以在名称空间中引入一个标签(在声明了read的名字空间中):

  #include< string> 
#include< vector>

namespace阅读{
模板< typename T>
struct Tag {};

模板< typename T>
T read()
{
T值;
read(Tag< T>(),value);
返回值;
}
} //命名空间读取

模板< typename T>
T read()
{
return Read :: read< T>();
}

namespace阅读{
void read(Tag< std :: string>,std :: string& str)
{
}

模板< typename T>
void read(Tag< std :: vector< T>>,std :: vector< T> vec)
{
}
} // namespace Read

int main(int argc,char ** argv){

read< std :: string>();
读取< std :: vector< int>>();
读< std :: vector< float>>();

返回0;

$ / code>

(注意:它也适用于全局名称空间)


Here is what Visual Studio compiles well:

#include <string>
#include <vector>

template <typename T>
T read()
{
    T value;
    read(value); // gcc compile error here
    return value;
}

void read(std::string& str)
{
}

template <typename T>
void read(std::vector<T>& vec)
{
}

int main(int argc, char** argv) {

    read<std::string>();
    read<std::vector<int>>();
    read<std::vector<float>>();

    return 0;
}

But GCC generates compile error: no matching function for call...

I found the only solution which works for me, to declare template function read(T&) before read():

template <typename T>
void read(T&);

template <typename T>
T read()
{
    T value;
    read(value);
    return value;
}

template <>
void read(std::string& str)
{
}

//template <typename T>
//void read(std::vector<T>& vec)
//{
//}

but I can't figure out how to fit template functions in it.

Is there any better ways to make gcc see functions declared after template which uses them, but before template's instantiation?

解决方案

To allow later overwrites (without forwarding) you may introduce a tag (in the namespace where read is declared) for name look up:

#include <string>
#include <vector>

namespace Read {
    template <typename T>
    struct Tag {};

    template <typename T>
    T read()
    {
        T value;
        read(Tag<T>(), value);
        return value;
    }
} // namespace Read

template <typename T>
T read()
{
    return Read::read<T>();
}

namespace Read {
    void read(Tag<std::string>, std::string& str)
    {
    }

    template <typename T>
    void read(Tag<std::vector<T>>, std::vector<T>& vec)
    {
    }
} // namespace Read

int main(int argc, char** argv) {

    read<std::string>();
    read<std::vector<int>>();
    read<std::vector<float>>();

    return 0;
}

(Note: It works in the global namespace, too)

这篇关于GCC中的模板没有看到在它之后声明的函数,但在实例化之前的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆