通过typedef强制模板实例化:在g ++上成功,在Visual C ++上失败 [英] Force template instantiation via typedef : success at g++ , fail at Visual C++

查看:62
本文介绍了通过typedef强制模板实例化:在g ++上成功,在Visual C ++上失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想强制模板实例化。

下面的代码在g ++上有效(打印 1 )( http://coliru.stacked-crooked.com/a/33986d0e0d320ad4 )。

但是在Visual C ++( https:// rextester上打印错误的结果( 0 ) .com / WGQG68063 )。

I want to force template instantiation.
The below code works (print 1) at g++ ( http://coliru.stacked-crooked.com/a/33986d0e0d320ad4 ).
However, it prints wrong result (0) at Visual C++ ( https://rextester.com/WGQG68063 ).

#include <iostream>
#include <string>
template <int& T>struct NonTypeParameter { };

//internal implementation
int lala=0;
template <typename T> struct Holder{
    static int init;
};
template <typename T> int Holder<T>::init = lala++;

//tool for user 
template <typename T> struct InitCRTP{ 
    using dummy=NonTypeParameter<Holder<T>::init>;
};

class WantInit : public InitCRTP<WantInit>{};//user register easily
int main(){
    std::cout << lala << std::endl;
}

这是Visual C ++编译器错误还是一种不确定的行为? br>
如果它是Visual C ++错误,如何解决(同时仍保持美观)?

Is it a Visual C++ compiler bug, or a kind of undefined behavior?
If it is Visual C++ bug, how to workaround it (while still keep it beautiful)?

编辑:按照Max Langhof(和很多人)的建议,更改类->结构。谢谢。

Change class -> struct as Max Langhof (and many people) recommended. Thank.

使用 StoryTeller的相反解决方案 Maxim Egorushkin 以及他们的深入讨论(谢谢!),这听起来像是C ++规则的模糊领域。

With opposite solutions from StoryTeller and Maxim Egorushkin and their in-depth discussion (thank!), this sounds like a fuzzy area of C++ rule.

如果它是Visual C ++错误,我希望这个问题一定可以报告。

If it is Visual C++ bug, I wish the issue to be certain enough to report.

此外,我仍然希望有一个不错的解决方法,因为此技术对于自定义type-id生成非常有用。显式实例化不是那么方便。

Moreover, I still wish for a nice workaround, because this technique is very shiny for custom type-id generation. Explicit instantiation is not so convenient.

注意:我授予了 Kaenbyou Rin 赏金,因为对我来说,这很容易理解。

这并不意味着其余答案不太正确或不太有用。

我仍​​然不确定哪个是正确的答案。读者应谨慎行事。

为了安全起见,我假设我暂时无法使用该功能。感谢大家。

Note: I awarded bounty to Kaenbyou Rin, because, for me, it is easy to understand.
It doesn't means that the rest of answers are less correct or less useful.
I am still not sure which is a correct one. Readers should proceed with caution.
For safety, I will assume that I just can't use the feature (for now). Thanks everyone.

推荐答案

肯定会涉及编译器错误。我们可以通过稍微更改 InitCRTP 来进行验证:

There is a compiler bug involved, for sure. We can verify it by changing InitCRTP a bit:

template <typename T, typename = NonTypeParameter<Holder<T>::init>>
struct InitCRTP {
};

现在引用任何 InitCRTP< T> 专业化必须使用 Holder< T> :: init 确定第二个模板参数。反过来,这应强制实例化 Holder< T :: init ,而 VS不会实例化

Now referring to any InitCRTP<T> specialization must use Holder<T>::init to determine the second template argument. This in turn should force an instantiation of Holder<T>::init, and yet VS doesn't instantiate that.

通常,使用CRTP类作为基础应该已经实例化了该类中的所有声明,包括 dummy

In general, using the CRTP class as a base should have instantiated all the declarations inside the class, including that of dummy. So that too should have worked.

我们可以进一步验证。成员函数的声明在用作基类时将与该类一起实例化。

We can verify it further. Declarations of member functions are instantiated along with the class, when used as a base:

template <typename T> struct InitCRTP{
    using dummy=NonTypeParameter<Holder<T>::init>;
    void dummy2(dummy);
};

还是, VC ++很固执。鉴于所有这些,以及Clang和GCC都表现出的行为,这是一个VC ++错误。

Still, VC++ is stubborn. Given all of this, and the behavior exhibited by both Clang and GCC, this is a VC++ bug.

这篇关于通过typedef强制模板实例化:在g ++上成功,在Visual C ++上失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆