2017-01-09 71 views
1

的靜態變量是我的代碼:未定義引用類模板下面

// types.h 
template <typename T> 
struct type_to_char {}; 

template <> 
struct type_to_char<char> { 
    static constexpr char str[] = "baz"; 
}; 


// main.cpp 
#include <iostream> 
#include <string> 

#include "types.h" 

int main() { 
    std::cout << type_to_char<char>::str << std::endl; 
    return 0; 
} 

在嘗試編譯,鏈接器返回一個錯誤: undefined reference to type_to_char<char>::str

我也遇到過this answer,但我不知道如何應用它在我的情況下,因爲模板沒有編譯。我應該在項目中放置一個單獨的文件.cpp嗎?

constexpr變量的聲明和定義有什麼區別?這樣的變量不能在沒有初始化器的情況下聲明,那麼爲什麼我應該在一個.cpp文件中放置一個單獨的定義?

我希望在這個

回答

2

由於您完全專門化一個類,它在很多方面的行爲就像一個未模糊的類。一個例子是它的靜態成員必須在實現文件中實例化,就像非模板類一樣。

// header file (type.h) 
template <typename T> 
struct type_to_char {}; 

template <> 
struct type_to_char<char> { 
    static constexpr char str[] = "baz"; 
}; 

// impementation file (type.cpp) 
constexpr char type_to_char <char>::str[]; 

// main.cpp 
#include <iostream> 
#include <type.h> 

int main() { 
    std::cout << type_to_char<char>::str << std::endl; 
    return 0; 
} 
1

您需要的是您的最終程序鏈接一個.cpp提供一個定義一些澄清。例如:

// types.h 
    template <typename T> 
    struct type_to_char {}; 

    template <> 
    struct type_to_char<char> { 
     static constexpr const char str[] = "baz"; 
    }; 


    // main.cpp 
    #include <iostream> 
    #include <string> 
    #include "types.h" 

    constexpr const char type_to_char <char>::str[]; 

    int main() { 
     std::cout << type_to_char<char>::str << std::endl; 
    } 
0

不能ODR使用靜態constexpr數據成員,除非你爲它提供了一個定義。
嘗試將ODR使用它是當你嘗試這樣做會發生什麼:

std::cout << type_to_char<char>::str << std::endl; 

這就是爲什麼需要一個定義。
您可以輕鬆地重現該問題,因爲它遵循:

struct S { static constexpr int x = 0; }; 
int main() { auto y = &S::x; (void)y; } 

不管怎樣,在特定情況下,它足以使用以下聲明:

static constexpr char *str = "baz"; 

如果可以用它代替數組類型,您不必明確定義type_to_char<char>::str