GCC中的模板没有看到在它之后声明的函数,但在实例化之前 [英] Template in GCC doesn't see a function declared after it, but before instantiation
问题描述
这是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屋!