C++ 如何链接嵌套的模板化专门化?
我希望能够使用通用字符串解析函数,如下所示:C++ 如何链接嵌套的模板化专门化?,c++,templates,linker-errors,C++,Templates,Linker Errors,我希望能够使用通用字符串解析函数,如下所示: Utils::parse::fromString<int>(whatever) Utils::parse::fromString<float>(whatever) Utils.ipp #ifndef UTILS_HPP_ #define UTILS_HPP_ #include <string> namespace Utils { namespace parse { templat
Utils::parse::fromString<int>(whatever)
Utils::parse::fromString<float>(whatever)
Utils.ipp
#ifndef UTILS_HPP_
#define UTILS_HPP_
#include <string>
namespace Utils
{
namespace parse
{
template<typename T>
T fromString(std::string s);
}
}
#include "Utils.ipp"
#endif // UTILS_HPP_
#ifndef UTILS_IPP_
#define UTILS_IPP_
template<>
int Utils::parse::fromString<int>(std::string s) { return 42; }
template<>
float Utils::parse::fromString<float>(std::string s) { return 42.0; }
#endif // UTILS_IPP_
#ifndef FOO_HPP_
#define FOO_HPP_
#include <string>
#include "Utils.hpp"
class Foo
{
public:
Foo();
template<typename T>
T get(std::string s);
};
#include "Foo.ipp"
#endif // FOO_HPP_
#ifndef FOO_IPP_
#define FOO_IPP_
#include <string>
template<typename T>
T Foo::get(std::string s)
{
return Utils::parse::fromString<T>(s);
}
#endif // FOO_HPP_
#include <iostream>
#include <string>
#include "Utils.hpp"
#include "Foo.hpp"
// Custom template specialization
template<>
char Utils::parse::fromString<char>(std::string s)
{
return 'c';
}
int main()
{
// Calling `fromString` directly - this works!
const std::string whatever = "whatever";
std::cout << Utils::parse::fromString<int>(whatever) << std::endl;
std::cout << Utils::parse::fromString<char>(whatever) << std::endl;
// Calling `fromString` via `Foo` - linking error!
Foo foo;
std::cout << foo.get<int>(whatever) << std::endl;
return 0;
}
Foo.ipp
#ifndef UTILS_HPP_
#define UTILS_HPP_
#include <string>
namespace Utils
{
namespace parse
{
template<typename T>
T fromString(std::string s);
}
}
#include "Utils.ipp"
#endif // UTILS_HPP_
#ifndef UTILS_IPP_
#define UTILS_IPP_
template<>
int Utils::parse::fromString<int>(std::string s) { return 42; }
template<>
float Utils::parse::fromString<float>(std::string s) { return 42.0; }
#endif // UTILS_IPP_
#ifndef FOO_HPP_
#define FOO_HPP_
#include <string>
#include "Utils.hpp"
class Foo
{
public:
Foo();
template<typename T>
T get(std::string s);
};
#include "Foo.ipp"
#endif // FOO_HPP_
#ifndef FOO_IPP_
#define FOO_IPP_
#include <string>
template<typename T>
T Foo::get(std::string s)
{
return Utils::parse::fromString<T>(s);
}
#endif // FOO_HPP_
#include <iostream>
#include <string>
#include "Utils.hpp"
#include "Foo.hpp"
// Custom template specialization
template<>
char Utils::parse::fromString<char>(std::string s)
{
return 'c';
}
int main()
{
// Calling `fromString` directly - this works!
const std::string whatever = "whatever";
std::cout << Utils::parse::fromString<int>(whatever) << std::endl;
std::cout << Utils::parse::fromString<char>(whatever) << std::endl;
// Calling `fromString` via `Foo` - linking error!
Foo foo;
std::cout << foo.get<int>(whatever) << std::endl;
return 0;
}
如果我只直接使用fromString
,它可以正常工作。但是,如果使用Foo
,则会出现“多定义”链接错误:
g++ test.cpp Foo.cpp
/tmp/cc7ACcVe.o: In function `int Utils::parse::fromString<int>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
Foo.cpp:(.text+0x0): multiple definition of `int Utils::parse::fromString<int>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
/tmp/ccrN171X.o:test.cpp:(.text+0x0): first defined here
/tmp/cc7ACcVe.o: In function `float Utils::parse::fromString<float>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
Foo.cpp:(.text+0xf): multiple definition of `float Utils::parse::fromString<float>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
/tmp/ccrN171X.o:test.cpp:(.text+0xf): first defined here
collect2: error: ld returned 1 exit status
g++test.cpp Foo.cpp
/tmp/cc7ACcVe.o:在函数“int-Utils::parse::fromString(std::_-cxx11::basic_-string)”中:
Foo.cpp:(.text+0x0):'int-Utils::parse::fromString(std::\uuucx11::basic\ustring)'的多个定义
/tmp/ccrN171X.o:test.cpp:(.text+0x0):首先在这里定义
/tmp/cc7ACcVe.o:在函数“float-Utils::parse::fromString(std::_-cxx11::basic_-string)”中:
Foo.cpp:(.text+0xf):'float-Utils::parse::fromString(std::\uuucx11::basic\ustring)'的多个定义
/tmp/ccrN171X.o:test.cpp:(.text+0xf):首先在这里定义
collect2:错误:ld返回了1个退出状态
虽然模板函数不需要内联
来避免多个定义,但专门化与常规函数一样
您必须添加它:
template <>
inline int Utils::parse::fromString<int>(std::string s) { return 42; }
template<>
inline float Utils::parse::fromString<float>(std::string s) { return 42.0; }
模板
内联int-Utils::parse::fromString(std::string s){return 42;}
模板
内联浮点Utils::parse::fromString(std::string s){return 42.0;}
相关/重复: