gpt4 book ai didi

c++ - undefined reference 、模板结构和 constexpr 静态成员

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:34:01 27 4
gpt4 key购买 nike

我在使用模板结构的静态 constexpr 成员时遇到了一些问题。代码编译但出现链接错误。这是我正在尝试做的事情:

template<int n>
struct Test {
static constexpr auto invoke = make_tuple(2, "test", 3.4);
};

template<typename T>
void test(T&& t) {
cout << t << endl;
}

int main() {
test(get<0>(Test<2>::invoke));
return 0;
}

我遇到了链接错误,所以我尝试了这个:

template<int n>
struct Test {
static constexpr auto invoke = make_tuple(2, "test", 3.4);
};

// declare it outside the class
template<int n>
constexpr decltype(Test<n>::invoke) Test<n>::invoke;

template<typename T>
void test(T&& t) {
cout << t << endl;
}

int main() {
test(get<0>(Test<2>::invoke));
return 0;
}

但是我得到了这个奇怪的错误:

error: redefinition of 'invoke' with a different type: 'const decltype(Test<n>::invoke)' vs 'const std::tuple<int, const char *, double>'

不同的类型??显然,非模板版本工作得很好:

struct Test {
static constexpr auto invoke = make_tuple(2, "test", 3.4);
};

constexpr decltype(Test::invoke) Test::invoke;

template<typename T>
void test(T&& t) {
cout << t << endl;
}

int main() {
test(get<0>(Test::invoke));
return 0;
}

如何让模板版本工作?非常感谢

最佳答案

看起来您遇到了一个有趣的 decltype 极端情况,clang 错误报告中对此进行了介绍 Static constexpr definitions used inside template其中有以下示例,错误与您的类似:

This compiles fine, but when I make the class A, a template like this:

struct L
{
void operator()() const
{}
};

template<class X>
struct A
{
static constexpr auto F = L();
};

template<class X>
constexpr decltype(A<X>::F) A<X>::F;

int main()
{
A<void>::F();
return 0;
}

Clang crashes, if I change the definition line for F to this:

template<class X>
constexpr typename std::remove_const<decltype(A<X>::F)>::type A<X>::F;

Then clang produces this error:

error: redefinition of 'F' with a different type
constexpr typename std::remove_const<decltype(A<X>::F)>::type A<X>::F;
^
note: previous definition is here
static constexpr auto F = L();
^

Richard Smith 的回复如下:

This error is correct. 'constexpr' and 'auto' are red herrings here. Reduced testcase:

template<class X> struct A { static int F; };
template<class X> decltype(A<X>::F) A<X>::F;

Per C++11 [temp.type]p2, "If an expression e involves a template parameter, decltype(e) denotes a unique dependent type." Therefore the type of A::F does not match the type in the template.

C++14 草案的完整引用如下:

If an expression e involves a template parameter, decltype(e) denotes a unique dependent type. Two such decltype-specifiers refer to the same type only if their expressions are equivalent (14.5.6.1). [ Note: however, it may be aliased, e.g., by a typedef-name. —end note ]

我能看到完成这项工作的唯一明显方法是:

template<int n>
constexpr decltype(make_tuple(2, "test", 3.4)) Test<n>::invoke;

错误报告中没有提供解决方法。

关于c++ - undefined reference 、模板结构和 constexpr 静态成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33337983/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com