模板varargs和显式实例化

时间:2014-07-22 15:32:02

标签: c++ templates c++11 variadic-templates constexpr

我试图一起使用几个新的C ++ 11功能。

#include <iostream>
#include <vector>


// Trying out template varargs.
template<typename T, T... args>
struct Test
{
    // Using constexpr
    // I had assumed that with this I did not need to
    // explicitly create an object `values`
    // that the compiler will work this out at compile time.
    static constexpr T              values[] = {args...};
};

// Explicitly instantiate
// the template to force it to generate the appropriate code. 
template struct Test<int, 1, 2, 3>;


typedef Test<int, 1, 2, 3>  TestInt;

int main()
{
    // Silly test to see if it worked.
    std::cout << TestInt::values[0] << "\n";
}

这会导致链接器失败。

> g++ -std=c++11 tp.cpp
Undefined symbols for architecture x86_64:
  "Test<int, 1, 2, 3>::values", referenced from:
      _main in tp-f3440e.o
ld: symbol(s) not found for architecture x86_64

我尝试了几种明确定义values数组的变体。但没有一个成功编译。

任何帮助表示感谢。

更新

显然,这是以他的榜样为@Nikos Athanasiou编写的 http://coliru.stacked-crooked.com/a/474fd3183db003f1

这是一个已知的编译器错误吗?

> g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix

1 个答案:

答案 0 :(得分:3)

values不仅仅是由初始化定义,但由于Test,初始化需要保留在constexpr内:

template<typename T, T... args> 
constexpr T Test<T, args...>::values[];

有关在GCC 4.9和Clang 3.4中有效的完整示例,请参阅here

#include <iostream>
#include <vector>


// Trying out template varargs.
template<typename T, T... args>
struct Test
{
    // Using constexpr
    // I had assumed that with this I did not need to
    // explicitly create an object `values`
    // that the compiler will work this out at compile time.
    static constexpr T values[] = {args...};
};

template<typename T, T... args> 
constexpr T Test<T, args...>::values[];

// Explicitly instantiate
// the template to force it to generate the appropriate code. 
template struct Test<int, 1, 2, 3>;


typedef Test<int, 1, 2, 3>  TestInt;

int main()
{
    // Silly test to see if it worked.
    std::cout << TestInt::values[0] << "\n";
}