Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何链接嵌套的模板化专门化?_C++_Templates_Linker Errors - Fatal编程技术网

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;}
相关/重复: