1. 程式人生 > 其它 >Understanding the Representation Power of Graph Neural Networks in Learning Graph Topology-NIPS2019

Understanding the Representation Power of Graph Neural Networks in Learning Graph Topology-NIPS2019

 

•共勉

  “那些瘋狂到以為自己能夠改變世界的人,才能真正改變世界。”

蘋果 “非同凡響” 廣告·1997    

•函式模板

介紹

  • C++另一種程式設計思想稱為 泛型程式設計 ,主要利用的技術就是模板
  • C++提供兩種模板機制:函式模板 和 類模板

函式模板

語法格式

template <typename T>//宣告一個模板,告訴編譯器後面程式碼中緊跟著的 T 不要報錯,T 是一個通用資料型別
函式宣告或定義
  • template:宣告建立模板
  • typename:表面其後面的符號是一種資料型別
  • T:通用的資料型別,名稱可以替換,通常為大寫字母

 

作用

  建立一個通用函式,其函式返回值型別和形參型別可以不具體制定,用一個虛擬的型別來代表。

 

舉例說明

  例如,對於如下交換函式:

void swapInt(int &a, int &b)
{
    int tmp = a;
    a = b;
    b = tmp;
}

  我們傳遞的引數只能是整數型別,如果我們想要交換 double 型別的呢?

  那當然是重寫一份啦~

void swapDouble(double& a, double& b)
{
    double tmp = a;
    a = b;
    b = tmp;
}

  對於這兩份程式碼,你會發現除了引數型別不同外,交換的步驟都是相同的。

  那如果要交換 short 型別的呢,在重寫一份嗎?

  會不會過於囉嗦,下面就引出函式模板的強大之處。

  我們可以這麼寫:

template <typename T>//宣告一個模板,告訴編譯器後面程式碼中緊跟著的T不要報錯,T是一個通用資料型別
void mySwap(T& a, T& b)
{
    T tmp = a;
    a = b;
    b = tmp;
}

  利用函式模板實現資料交換,有兩種呼叫方式:

  • 自動型別推導
  • 顯示指定型別
void test()
{
    int a = 10;
    int b = 20;

    mySwap(a, b);//1.自動型別推到
    cout << "
a = " << a << endl; cout << "b = " << b << endl; double c = 30; double d = 40; mySwap<double>(c, d);//2.顯示指定型別 cout << "c = " << c << endl; cout << "d = " << d << endl; }

  對於方式 1,編譯器會自動識別傳遞的引數型別,並做相應的調整:

 

注意事項 1

  傳遞的引數型別必須是同種型別的,即必須推匯出一致的資料型別 T 才可以使用。

  比如就不能通過  mySwap  函式交換 int 和 double 型別的資料:

void test()
{
    int a = 10;
    double b = 20;
    myswap(a, b);
}

  由於 a,b 不是同種型別的,在編譯階段就會報錯:

  提示推導不出一致的 T 型別。

 

注意事項 2

  必須遵循模板的宣告和函式的宣告一對一使用,即模板的宣告只作用於緊挨著的函式宣告。

  比如下面這種程式碼就會報錯:

template <typename T>
void func1(T &a){}
void func2(T &a){}

  因為宣告的函式模板 T 只對  func1  起作用,如果  func2  也想用,必須重新宣告:

template <typename T>
void func1(T &a) {}

template <typename T>
void func2(T &a) {}

 注意事項 3

   模板必須要確定出 T 的資料型別,才可以使用。

  比如如下程式碼就會報錯:

template <typename T>
void func() {}
void test()
{
    func();
}

  因為函式  func()  的宣告緊挨著模板的宣告,所以他倆就是一對一的關係,那麼要想呼叫  func ,就必須給出 T 的資料型別;

  不然編譯階段都不通過。

  對於這種不含引數的函式模板,必須使用 顯示指定型別 來呼叫:

template <typename T>
void func() {}
void test()
{
    func<int>();
}

  其中 <int> 隨便寫個資料型別就行,作用就是告訴函式模板傳遞的 T 為  XX 型別 。

•學以致用

  有了函式模板的知識儲備,下面來寫一個排序函式,不管是傳入  int 型別  還是  char 型別  都可以實現升序排列。

選擇排序

template <typename T>
void mySwap(T& a, T& b)
{
    T tmp = a;
    a = b;
    b = tmp;
}
template <typename T>
void mySort(T arr[],int first,int last)//order [first, last)
{
    for (int i = first; i < last; i++)//選擇排序
    {
        int minIndex = i;
        for (int j = i + 1; j < last; j++)
        {
            if (arr[j] < arr[minIndex])
                minIndex = j;
        }
        mySwap(arr[i], arr[minIndex]);
    }
}

呼叫該排序函式

template <typename T>
void print(const T arr[], int first, int last)//輸出陣列[first, last)
{
    for (int i = first; i < last; i++)
        cout << arr[i] << " ";
    cout << endl;
}
void test1()
{
    //測試對整形陣列進行排序
    int arr[10];
    for (int i = 0; i < 10; i++)
        arr[i] = rand()%20;//隨機產生[0~20)之間的隨機數

    cout << "排序前:";
    print(arr, 0, 10);
    mySort(arr, 0, 10);
    cout << "排序後:";
    print(arr, 0, 10);
}
void test2()
{
    //測試對字元型陣列進行排序
    char arr[10];
    for (int i = 0; i < 10; i++)
        arr[i] = 'A'+rand() % 20;//隨機產生[0~20)之間的隨機數

    cout << "排序前:";
    print(arr, 0, 10);
    mySort(arr, 0, 10);
    cout << "排序後:";
    print(arr, 0, 10);
}

CODE

#include<bits/stdc++.h>
using namespace std;

template <typename T>
void mySwap(T& a, T& b)
{
    T tmp = a;
    a = b;
    b = tmp;
}
template <typename T>
void mySort(T arr[],int first,int last)//order [first, last)
{
    for (int i = first; i < last; i++)//選擇排序
    {
        int minIndex = i;
        for (int j = i + 1; j < last; j++)
        {
            if (arr[j] < arr[minIndex])
                minIndex = j;
        }
        mySwap(arr[i], arr[minIndex]);
    }
}
template <typename T>
void print(const T arr[], int first, int last)//輸出陣列[first, last)
{
    for (int i = first; i < last; i++)
        cout << arr[i] << " ";
    cout << endl;
}
void test1()
{
    //測試對整形陣列進行排序
    int arr[10];
    for (int i = 0; i < 10; i++)
        arr[i] = rand()%20;//隨機產生[0~20)之間的隨機數

    cout << "排序前:";
    print(arr, 0, 10);
    mySort(arr, 0, 10);
    cout << "排序後:";
    print(arr, 0, 10);
}
void test2()
{
    //測試對字元型陣列進行排序
    char arr[10];
    for (int i = 0; i < 10; i++)
        arr[i] = 'A'+rand() % 20;//隨機產生[0~20)之間的隨機數

    cout << "排序前:";
    print(arr, 0, 10);
    mySort(arr, 0, 10);
    cout << "排序後:";
    print(arr, 0, 10);
}
int main()
{
    test1();
    test2();
    return 0;
}

•結尾

  咳咳,本次內容到此結束,完結撒花