Pin-Jiun / Programming-Language-CPP

It's the note/experience about C++, and I have the basic ability of C.
0 stars 0 forks source link

19-auto and decltype #26

Open Pin-Jiun opened 1 year ago

Pin-Jiun commented 1 year ago

auto

在 C++11 標準下,讓編譯器在編譯時期自動判斷其變數的類型,不會造成明顯的額外的負擔。

#include <cmath>
int main() {
  // 等同於 int x = 1;
  auto x = 1;
  // 等同於 double y = sin(1.3);
  auto y = sin(1.3);
  return 0;
}

在 C++11 的標準中,auto 不可以用於函數的傳回值,但後來C++14的標準加入了這個用法

// 在 C++11 中無法使用,但 C++14 則可以
auto my_fun() {
  int value = 3;
  return value;
}

decltype (declare_type)

透過decltype來定義一個和a一樣的type

void main() {
    int a = 10;
    decltype(a) b;

    b = 123;

    std::cout << b << std::endl;
}

因為a的type為int所以b的type也是int

開發人員無法確定一個表達式exp()的值類型,然而需要聲明一個與之類型匹配的變數,則可以如下聲明:

decltype(exp()) x;

decltype通常是在寫generic code的時候

#include <iostream>
#include <vector>

class CBuilderA
{
public:
    int DoSomething() const { return 10; }
};

class CBuilderB
{
public:
    float DoSomething() const { return 10.2f; }
};

template<typename B>
void Foo(const B& builder)
{
    decltype(builder.DoSomething()) val = builder.DoSomething();

    //You can use auto to do the same thing
    auto val2 = builder.DoSomething();

    //That's why we need decltype 
    std::vector<decltype(val)> vec;
    vec.push_back(val);
    vec.push_back(val2);

    std::cout << vec[0]  << ", " << vec[1] << std::endl;
}

void main()
{
    CBuilderA a;
    Foo(a);

    CBuilderB b;
    Foo(b);
}

但是在上述範例中,當我們要把val和val2都放到vector裡面去的時候,問題就來了:這個vector要存放的type到底是什麼?這時候只能用std::vector<decltype(val)> vec;來解決這個問題(這是auto辦不到的地方)。

參考資料 https://coherence0815.wordpress.com/2015/08/25/decltype-in-c11/