简体   繁体   English

防止隐式模板实例化

[英]Prevent implicit template instantiation

In a method overload situation like this:在这样的方法重载情况下:

struct A
{
  void foo( int i ) { /*...*/ }
  template<typename T> void foo( T t ) { /*...*/ }
}

How can I prevent template instantiation unless explicitly commanded?:除非明确命令,否则如何防止模板实例化?:

A a;
a.foo<int>( 1 ); // ok
a.foo<double>( 1.0 ); // ok
a.foo( 1 ); // calls non-templated method
a.foo( 1.0 ); // error

Thanks!谢谢!

You can introduce a depedent_type struct that prevents template argument deduction .您可以引入一个depedent_type结构来防止模板参数推导

template <typename T>
struct dependent_type
{
    using type = T;
};

struct A
{
  void foo( int i ) { /*...*/ };
  template<typename T> void foo( typename dependent_type<T>::type t ) { /*...*/ }
}

Which in your example:在您的示例中:

a.foo<int>( 1 );      // calls the template
a.foo<double>( 1.0 ); // calls the template
a.foo( 1 );           // calls non-templated method
a.foo( 1.0 );         // calls non-templated method (implicit conversion)

wandbox example 魔杖盒示例

(This behavior is explained on cppreference > template argument deduction > non-deduced contexts .) (此行为在cppreference >模板参数推导>非推导上下文中进行了解释。)


If you want to make a.foo( 1.0 ) a compilation error, you need to constrain the first overload:如果要使a.foo( 1.0 )成为编译错误,则需要约束第一个重载:

template <typename T> 
auto foo( T ) -> std::enable_if_t<std::is_same<T, int>{}> { }

This technique makes the above overload of foo take only int arguments: implicit conversions (eg float to int ) are not allowed.这种技术使上面的foo重载只接受int参数:不允许隐式转换(例如floatint If this is not what you want, consider TemplateRex's answer.如果这不是您想要的,请考虑 TemplateRex 的答案。

wandbox example 魔杖盒示例

(With the above constrained function, there is a curious interaction between the two overloads when a.foo<int>( 1 ) is called. I asked a question about it as I'm not sure of the underlying rules that guide it.) (使用上述受约束的函数,当a.foo<int>( 1 )被调用时,两个重载之间存在奇怪的交互。我问了一个问题,因为我不确定指导它的底层规则。)

By far the simplest way to do what you want is to explicitly delete the overload you don't want:到目前为止,做你想做的最简单的方法是显式删除你不想要的重载:

void foo(double) = delete;

Ie to have the following explicit example:即有以下明确的例子:

#include <iostream>

struct A
{
    void foo(int) { std::cout << __PRETTY_FUNCTION__ << "\n"; }
    void foo(double) = delete;

    template<typename T> 
    void foo( T ) {std::cout << __PRETTY_FUNCTION__ << "\n"; }
};

int main() 
{    
    A a;
    a.foo<int>( 1 );        // ok
    a.foo<double>( 1.0 );   // ok
    a.foo( 1 );             // calls non-templated method
    a.foo( 1.0 );           // error    
}

With the last line in main commented out this prints main 中的最后一行注释掉了这个打印

void A::foo(T) [with T = int] void A::foo(T) [with T = double] void A::foo(int)

and with the last line left in this prints并在此打印中留下最后一行

prog.cc: In function 'int main()': prog.cc:18:16: error: use of deleted function 'void A::foo(double)' a.foo( 1.0 ); // error ^ prog.cc:6:10: note: declared here void foo(double) = delete;

Adding another suggestion to the pot, and in a similar vein as Vittorio's answer you can also add another template parameter to the signature:向锅中添加另一个建议,与 Vittorio 的回答类似,您还可以向签名添加另一个模板参数:

template <class UserType, class InputType>
void foo(InputType x){...}

Then to use it you must specify the first template parameter as it cannot be deduced.然后要使用它,您必须指定第一个模板参数,因为它无法推导出来。 This has the slight advantage of being able to distinguish between what the user wanted and what was passed in, which could possibly be of use in some cases.这具有能够区分用户想要的和传入的内容的轻微优势,这在某些情况下可能有用。

Halelulah!!!!!!!哈利路拉!!!!!! I finally found the answer after years of grief.经过多年的悲伤,我终于找到了答案。 Cause I knew that cpp rule, seperate declaration from definition was not just thrown in the dump!!!因为我知道 cpp 规则,定义中的单独声明不只是被扔到转储中!!!

// declare template
template <class T> void test();

// declare specialization
template <> // very import to start with this token
void<int> test();

// implicit instantiation
template // if you use this instead, you get instantiation
void<int> test();

I still wonder why this is necessary.我仍然想知道为什么这是必要的。 Probably it is an optimization from those wise people of the Cpp Committee.大概是中共那些智者的优化吧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM