当前位置:网站首页>Clause 30: be familiar with the failure of perfect forwarding

Clause 30: be familiar with the failure of perfect forwarding

2022-06-13 04:55:00 CCSUZB

“ forward ” It means that a function passes its parameters ( forward ) Just give another function . The meaning of perfect forwarding is that we not only forward objects , It also forwards its salient features : type , The left value , Right value , And whether it has const or volation Modifiers, etc .

Suppose there is a function f, Then we are going to write a function that will f As a forwarding target , Consider the following code :

template<typename T>
void fwd(T && param) {
    			// Accept arbitrary arguments 
	f(std::forward<T>(param));	// Forwarding to f
}

Given the objective function f And forwarding functions fwd, When with a specific argument f Can perform an operation , And call... With the same argument fwd Can perform different operations , It is called perfect forwarding failure :

f(experssion);	//  If this statement does something 
fwd(experssion);//  This statement performs different operations , said fwd Perfect forwarding experssion To f Failure 

The following explains the arguments that cannot implement perfect forwarding one by one

Brace initializer

hypothesis f The statement is as follows :

void f(const std::vector<int> &);

f({
    1, 2, 3});	//  That's all right. ,{1, 2, 3} Will implicitly convert std::vector<int>

fwd({
    1, 2, 3}); //  error !  Unable to compile 

Above fwd For the use of brace initializers , It's a case of perfect forwarding failure ; Via the forwarding function template fwd Come on f When implementing an indirect call , The compiler will no longer compare fwd The shape parameter declared by the passed in argument at the call . Perfect forwarding fails when the following conditions are true

  1. The compiler cannot create a file for one or more fwd To derive the type result
  2. The compiler is one or more fwd The formal parameters of are derived “ FALSE ” Type the results

0 and NULL Used as a null pointer

Clause 8 Said , If you try to put 0 and NULL Pass null pointer to function template , Type derivation will lead to behavior distortion , The result will be an integer . The conclusion is that :0 and NULL Can't be used as a null pointer for perfect forwarding

Only declared integers static const Member variables

Consider the following code :

class widget {
    
public:
    static const std::size_t MinVals = 28;		//  give MinVals Statement 
};

void f(std::size_t val) {
    
    cout << "this is f fuxntion";
}

template<typename T>
void fwd(T && param) {
    			// Accept arbitrary arguments 
    f(std::forward<T>(param));	// Forwarding to f
}

std::vector<int> widgetData;
widgetData.reserve(widget::MinVals);

f(widget::MinVals);				//  No problem , When f(28) Handle 
fwd(widget::MinVals);			//  error , Should not be able to link 

Overloaded function name and template name

Consider the following code :

int processval(int value) {
    
    return 0;
}

int processval(int value, int priority) {
    
    return 1;
}

f(processval);		//  No problem 

Above f in call , Compilers know what they need to call processVal. however fwd Is that all right , Because as a function template , It doesn't have any information about type requirements , This also makes it impossible for the compiler to decide which function overloaded version should be passed

fwd(processVal); 	//  error ! Which one? processVal Overload version ?

Bit field

void f(std::size_t sz) {
    
    std::cout << "this is f function";
}

template<typename T>
void fwd(T &&param) {
    
    f(std::forward<T>(param));
}

IPv4Header h;
f(h.totalLength);	//  That's all right. 
fwd(h.totalLength); //  error !  Not const References must not be bound to domain 
原网站

版权声明
本文为[CCSUZB]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202280518034457.html