【问题标题】:add function member to a template class conditionally [duplicate]有条件地将函数成员添加到模板类[重复]
【发布时间】:2020-03-20 04:27:55
【问题描述】:

我有一个定义如下的类模板

template<typename T>
class A
{
  T t_;
  // void f();
};

我的问题是,只有在类型 T 是整数且没有编译错误的情况下,如何添加 f() 方法。

int main()
{
  A<int> a; // OK
  A<string> b; // OK
}

例子:

#include <type_traits>
#include <new>
#include <iostream>
#include <string>



template <typename T>
struct Foo
{
    T t;
    template <typename..., typename U = T>
    std::enable_if_t<std::is_same_v<T, int>> say_hello() { std::cout << "Hello"; }
};


int main()
{
    Foo<int>();
    Foo<double>();
}
Error   C2938   'std::enable_if_t<false,void>' : Failed to specialize alias template

谢谢。

【问题讨论】:

标签: c++ templates sfinae


【解决方案1】:

您可以使用type_traits 和 SFINAE 启用特定功能:

#include <iostream>
#include <string>
#include <type_traits>

template<typename T>
class A
{
public:
    template<typename U = T, std::enable_if_t<std::is_integral_v<U>, int> = 0>
    void f() {
        std::cout << "int " << t_ << '\n';
    }
private:
    T t_;
};


int main() {
    A<int> a;
    a.f();

    A<std::string> s;
    // s.f(); //  error: no member named 'f' in 'A<std::__cxx11::basic_string<char> >'
}

如果您有许多特定于整数的函数,则可以将它们放在自己的类中,并且仅当 T 是整数时才继承该类。

#include <iostream>
#include <string>
#include <type_traits>

template<typename Atype>
class int_functions {
public:
    Atype* This() { return static_cast<Atype*>(this); }

    void f() {
        std::cout << "int " << This()->t_ << '\n';
    }
};

template<typename Atype>
class non_int_functions {
};

template<typename T>
class A : public std::conditional_t<std::is_integral_v<T>, int_functions<A<T>>,
                                                           non_int_functions<A<T>>>
{
    friend std::conditional_t<std::is_integral_v<T>, int_functions<A<T>>,
                                                     non_int_functions<A<T>>>;
public:
private:
    T t_;
};

【讨论】:

  • 我没有整数类型的特殊功能。它只有一个功能。我尽量避免复制粘贴代码
  • @Roger 好的,为这种情况添加了一个更简单的解决方案。不过,使用我的第一个建议不会有任何复制/粘贴。
猜你喜欢
  • 2017-01-02
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
  • 2011-01-01
相关资源
最近更新 更多