[C ++ 11具有空类型和参数的模板专业化

问题描述 投票:0回答:2

C ++ 11程序中,我定义了这些模板:

namespace outcome {

template <class T>
class c_out {
    public:
        bool success = false;
        std::string error = "";
        T result;
};

template <class T>
c_out<T> failed(T res, const std::string& error_msg = "") {
    c_out<T> outcome;
    outcome.success = false;
    outcome.error = error_msg;
    return outcome;
};

template <class T>
c_out<T> succeeded(T res) {
    c_out<T> outcome;
    outcome.success = true;
    outcome.result = res;
    return outcome;
};

};

我想在class Tvoid时专门化它们。对于c_out

来说很容易解决
template <>
class c_out<void> {
    public:
        bool success = false;
        std::string error = "";
};

但是,其他两个功能仍然出错。我如何专门化它们?

c_out<void> failed(const std::string& error_msg = "") {
    c_out<void> outcome;
    outcome.success = false;
    outcome.error = error_msg;
    return outcome;
};

c_out<void> succeeded(void) {
    c_out<void> outcome;
    outcome.success = true;
    return outcome;
};

错误:当我致电

outcome::succeeded();

YYY.cpp中,链接库时出错:

lib/libXXX.a(YYY.cpp.o): In function `outcome::failed(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
YYY.cpp:(.text+0x0): multiple definition of `outcome::failed(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
CMakeFiles/ZZZ.dir/main/main.cpp.o:main.cpp:(.text+0x0): first defined here
lib/libXXX.a(YYY.cpp.o): In function `outcome::succeeded()':
YYY.cpp:(.text+0x50): multiple definition of `outcome::succeeded()'
CMakeFiles/ZZZ.dir/main/main.cpp.o:main.cpp:(.text+0x50): first defined here
c++ c++11 templates
2个回答
0
投票

不是专业。那些是超负荷的。它们是常规函数,这一点很重要,因为缺省情况下,函数模板专业化具有一些常规函数没有的属性。

例如,模板可以出现在标题中,因此可以在多个翻译单元中定义而不会出现问题。模板为隐式内联。常规函数需要显式内联。

您的错误表明您在头文件中定义了这些重载。将其包含在多个翻译单元中会导致出现多个定义,并且这些函数不是内联的,所以那是一个格式错误的程序。

解决方案是将这些重载移至专用TU,并仅公开其声明。或者,您可以在标头中内联标记它们:

inline c_out<void> failed(const std::string& error_msg = "") {
    c_out<void> outcome;
    outcome.success = false;
    outcome.error = error_msg;
    return outcome;
};

inline c_out<void> succeeded(void) {
    c_out<void> outcome;
    outcome.success = true;
    return outcome;
};

这将在每个TU中吐出一个内联定义。只要所有定义都完全相同(对于标头中的函数而言确实如此),程序就会格式正确。


0
投票

1。请确保在编译时不要使用其他文件。例如,如果您将模板类放入头文件中,而将主类放入不同的.cpp文件中,这可能会导致程序崩溃,因为它在.cpp文件中搜索模板(上述情况不存在)。这可能是问题的原因。

  1. 某些IDE没有这个问题,所以您可能想尝试另一个IDE并检查是否出现相同的错误。
© www.soinside.com 2019 - 2024. All rights reserved.