【问题标题】:Simple template class member function specialization that returns a value返回值的简单模板类成员函数特化
【发布时间】:2018-11-21 05:58:03
【问题描述】:

我正在尝试调用从类的构造函数中返回值的模板类成员函数特化,但我似乎找不到正确的语法(如果存在)。下面是我的代码,下面是来自编译器(不是链接器)的错误消息。

#include <iostream>

class A {};

class B {};

template <typename T>
class C
{
    public:
        C()
        {
            std::cout << "C constructed." << std::endl;
            std::cout << name() << std::endl;;
        }
        template constexpr const char * name();
};

template <> const char * C<A>::name() { return "You got an A."; }
template <> const char * C<B>::name() { return "You got a B."; }


int main()
{
    C<A> c_a;
    C<B> c_b;
    return 0;
}

错误信息: g++ -std=c++11 -o t1 t1.cpp t1.cpp:19:18: 错误: 'constexpr' 之前的预期'' 与任何模板声明都不匹配 template const char * C::name() { return "你有一个 A."; } ^ t1.cpp:22:37: note: saw 1 ‘template’, 需要 2 来专门化成员函数模板 template const char * C::name() { return "你有一个 A."; } ^ t1.cpp:23:26: 错误:'const char* C::name()' 的模板 ID 'name' 与任何模板声明都不匹配 模板 const char * C::name() { return "你有一个 B."; } ^ t1.cpp:23:37: note: saw 1 ‘template’, 需要 2 来专门化成员函数模板 模板 const char * C::name() { return "你有一个 B."; }

我已搜索并发现 许多 讨论关于引发此错误消息的代码,但案例和建议似乎都不够接近以至于无法相关。此外,如果我不尝试从专门的成员函数返回任何内容——如果它具有返回类型 void 并且只是打印到 cout——那么它会像我一样工作期望,即,我看到具有正确值的打印文本。

有可能做我想做的事吗?如果是这样,怎么做?谢谢!

【问题讨论】:

  • name() 函数本身不是模板,那么为什么要使用 template
  • 你是对的。我真正想要的是一个类的特化的成员函数,但我使用的语法好像它是该模板类的模板函数的特化。这是我的错误。 (请参阅我的解决方案。)谢谢。
  • 糟糕!在我写上述回复时,有人发布了一个与我找到的解决方案相同的解决方案。谢谢!

标签: c++ c++11 templates template-specialization


【解决方案1】:

语法是:

template <typename T>
class C
{
    public:
        C()
        {
            std::cout << "C constructed." << std::endl;
            std::cout << name() << std::endl;;
        }
        constexpr const char* name();
};

template <> constexpr const char * C<A>::name() { return "You got an A."; }
template <> constexpr const char * C<B>::name() { return "You got a B."; }

Demo

【讨论】:

  • 谢谢,但这不适用于我的 GCC: $ g++ -std=c++11 -o t1 t1.cpp t1.cpp: In member function 'constexpr const char* C ::name() const [with T = A]': t1.cpp:60:36: error: enclosure class of constexpr non-static member function 'constexpr const char* C::name() const [with T = A]' 不是文字类型
  • 您收到警告:"'C&lt;A&gt;' 不是文字,因为:C&lt;A&gt; 不是聚合,没有简单的默认构造函数,也没有 constexpr 构造函数不是复制或移动构造函数”。所以你必须至少满足一点作为提供constexpr构造函数(Demo)。
【解决方案2】:

你有点复杂了。函数声明中不需要“模板”。它只是一个恰好位于类模板中的普通函数,并且您想针对某些 T 专门化它。这是一种方法:

#include <iostream>

class A {};
class B {};

template <typename T>
class C {
public:
    C() {
        std::cout << "C constructed." << std::endl;
        std::cout << name() << std::endl;;
    }
    static constexpr const char * name();
};

template <> constexpr const char * C<A>::name() { return "You got an A."; }
template <> constexpr const char * C<B>::name() { return "You got a B."; }

int main() {
    C<A> c_a;
    C<B> c_b;
}

【讨论】:

  • 你是对的!它根本不需要是实例成员函数。我只是不知道如何为静态函数获得正确的语法。谢谢!
【解决方案3】:

作为记录,我找到了解决我发布的确切问题的方法——即使用成员函数而不是静态(或全局)函数here

#include <iostream>

class A {};
class B {};

template <typename T>
class C
{
    template <typename U> struct type {};
    public:
        C()
        {
            std::cout << "C constructed." << std::endl;
            std::cout << name<T>() << std::endl;;
        }
        template <typename U> constexpr const char * name()
        {
            return name(type<U>());
        }


    private:
        template <typename U> constexpr const char * name(type<U>) {}
        constexpr const char * name(type<A>) { return "You got an A."; }
        constexpr const char * name(type<B>) { return "You got an B."; }
};

int main()
{
    C<A> c_a;
    C<B> c_b;
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    • 2011-08-22
    相关资源
    最近更新 更多