2017-01-09 64 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