【问题标题】:Check for template type parameter, during compile time, for type specific operation在编译期间检查模板类型参数以进行特定于类型的操作
【发布时间】:2020-11-21 06:09:47
【问题描述】:

首先,代码仅限于C++11,所以无法使用if constexpr

以下是我的示例代码 sn-p:

class A{
 public:
    int a;
    int b;
}

class B{
 public:
    int key;
    int val;
}

class C{
 public:
    int n1;
    int n2;
}

class D{
 public:
    int n1;
    int n2;
}

class E{
 public:
    int n1;
    int n2;
}

template<typename T>
void func1(T data) {
   if (T == type(A)) {             // Just pseudo template-check code
    std::cout<<data.a<<data.b;              //<------1
   } else if (T == type (B)) {    // Just pseudo template-check code
    std::cout<<data.key<<data.val;          //<------2
   } else {
    std::cout<<data.n1<<data.n2;            //<------3
}


int main() {
A a;
B b;
C c;
D d;
E e;

func1(a);
func1(b);
func1(c);
func1(d);
func1(e);

return 0;
}

目前,我收到一个编译时错误,

1: B,D,E,F has no member a & b
 & 
2: A,D,E,F has no member key & val
 &
3. A, B has no member n1 & n2

我尝试使用is_same()this,但每次都会遇到相同的编译时错误。

  1. 我无法使用 C++14/C++17
  2. 如何使用专门的模板函数?

编辑代码以突出模板的需要。

【问题讨论】:

  • 你想要完成的工作中有哪一部分是老式的、直截了当的、专业化的无法完成的?
  • 一个相对现实的用法,包括main 将是巨大的,因为到目前为止,我认为除了提供两个不同的功能之外没有理由做任何事情。 std::cout&lt;&lt;T.a&lt;&lt;T.b; 纯属幻想;它不是远程有效的代码。 func1 没有参数,因此调用者完全负责在调用点提供AB 作为模板参数。如果您要这样做,您可能首先要调用两个不同的函数,无论是专业化还是其他。
  • 更新后,现在问问自己,为什么完全模板化?为什么不直接使用 func1 和两个重载:void func1(A data)void func1(B data)
  • 在您的示例中,您根本不需要模板。只需定义 func1 的 2 个重载。
  • 您需要多少通用性?你得到的答案对AB 很好。可以让它适用于任何类型,但值得吗?

标签: c++ c++11 templates


【解决方案1】:

您必须为要使用的两种类型编写函数的特化。

#include<iostream>

class A{
 public:
    int a;
    int b;
};

class B{
 public:
    int key;
    int val;
};

template<typename T>
void func1(T);

template<>
void func1<A>(A arg) {
    std::cout<<"A"<<std::endl;
    std::cout<<arg.a<<arg.b;
}

template<>
void func1<B>(B arg) {
    std::cout<<"B"<<std::endl;
    std::cout<<arg.key<<arg.val;
}

int main(){
A a;
func1(a);

B b;
func1(b);

}

【讨论】:

    【解决方案2】:

    您可以使用函数重载并完全避免使用函数模板。

    void func1(A a)
    {
       // Type dependent code.
    }
    
    void func1(B a)
    {
       // Type dependent code.
    }
    

    只有当函数调用所针对的所有类型都有通用代码时,函数模板才有意义。如果你有一些对所有类型都通用的代码和一些依赖于类型的代码,那么你可以使用:

    void func1(A a)
    {
       // Type dependent code.
    }
    
    void func1(B a)
    {
       // Type dependent code.
    }
    
    template <typename T>
    void func2(T t)
    {
       // Type independent code.
    }
    
    template <typename T>
    void func(T obj)
    {
       func1(obj);   // Call function that uses type dependent code.
       func2(obj);   // Call function that uses type independent code.
    }
    
    

    【讨论】:

    • 为什么要介绍fun2
    • @MarekR,展示如何拆分类型相关代码和类型无关代码。
    【解决方案3】:

    简单的重载就可以了。

    template <typename T>
    void func1(T data)
    {
        std::cout << data.n1 << data.n2;
    }
    
    void func1(A data)
    {
        std::cout << data.a << data.b;
    }
    
    void func1(B data)
    {
        std::cout << data.key << data.val;
    }
    

    https://godbolt.org/z/r7Ee6E
    稍作调整:https://godbolt.org/z/xxPWaE

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-17
      • 1970-01-01
      • 2013-10-13
      • 2014-03-31
      • 1970-01-01
      • 2021-02-18
      相关资源
      最近更新 更多