简体   繁体   English

由于 if constexpr,内联模板化 function 具有不同的行为是否违反 ODR?

[英]Is it an ODR violation to have an inline templated function have different behavior due to if constexpr?

It's possible to detect if a type is complete https://devblogs.microsoft.com/oldnewthing/20190710-00/?p=102678可以检测类型是否完整https://devblogs.microsoft.com/oldnewthing/20190710-00/?p=102678

I have reason to want to provide a different (inlinable) implementation if a type is complete.如果一个类型是完整的,我有理由想要提供一个不同的(可内联的)实现。

Is it an ORD violation for a templated function to behave differently in different translation units based on an if constexpr in the function?模板化的 function 在基于 function 中的if constexpr的不同翻译单元中表现不同是否违反了 ORD? In a sense, it's the "same" function in the different translation units (it's not macros creating different definitions at a C++ source level, which is an ODR violation).从某种意义上说,它是不同翻译单元中的“相同”function(它不是在 C++ 源级别创建不同定义的宏,这是 ODR 违规)。

Here's a simple example:这是一个简单的例子:

#include <iostream>
#include <type_traits>


// From https://devblogs.microsoft.com/oldnewthing/20190710-00/?p=102678
template<typename, typename = void>
constexpr bool is_type_complete_v = false;

template<typename T>
constexpr bool is_type_complete_v
    <T, std::void_t<decltype(sizeof(T))>> = true;


template <typename T>
T* loggingGetRef(T* x) {
    if constexpr (is_type_complete_v<T>) {
        std::cout << "Complete!" << std::endl;
    } else {
        std::cout << "Incomplete!" << std::endl;
    }
    return x;
}

struct S
//{} // <- Uncomment this to make loggingGetRef be "different" through if constexpr.
;

int main() {    
    S* ptr = nullptr;
    loggingGetRef(ptr);    
}

https://godbolt.org/z/q1soa58PY https://godbolt.org/z/q1soa58PY

For my application, I would want the two if constexpr branches to outwardly act the same (unlike this example that prints different things) so from a correctness standpoint, it would be OK if the linker picked the assembly for either implementation and used that everywhere.对于我的应用程序,我希望这两个if constexpr分支在外观上表现相同(不像这个打印不同内容的示例),因此从正确性的角度来看,如果 linker 选择程序集用于任一实现并在任何地方使用它就可以了。 It's just that in a translation unit where T is complete we may be able to get better performance (and I fully expect it to be inlined).只是在T完整的翻译单元中,我们可能可以获得更好的性能(我完全希望它是内联的)。

ODR is not based on "templated functions"; ODR 不是基于“模板函数”; it is based on actual functions.它基于实际功能。 Templates generate functions based on template parameters.模板根据模板参数生成函数。 Each unique set of template parameters represents a different function. Different functions generated from the same template are different functions .每组唯一的模板参数代表一个不同的function。同一个模板生成的不同函数是不同的函数 There are no ODR expectations between different functions, regardless of what created them.不同功能之间没有 ODR 期望,无论创建它们的原因如何。

loggingGetRef<S> is the name of a particular function. If you do something that causes loggingGetRef<S> to generate differently due to constant expressions, you have ill-formed code (no diagnostic required). loggingGetRef<S>是特定 function 的名称。如果您执行的操作导致loggingGetRef<S>由于常量表达式而生成不同的内容,则您的代码格式错误(无需诊断)。 But that isn't a matter of ODR violations;但这不是 ODR 违规的问题; that's a violation of the rules of template instantiation.这违反了模板实例化规则。 A template that is instantiated with a specific set of parameters must be the same in all translation units that instantiate it with those parameters.使用一组特定参数实例化的模板在使用这些参数实例化它的所有翻译单元中必须相同。 Period.时期。

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

相关问题 具有内联函数的不同定义是不确定的行为? - Is it an undefined behavior to have different definitions of an inline function? 在声明中使用不一致的 noexcept 是否违反 ODR? - Is it an ODR violation to have inconsistent noexcept in declaration? 在内联和constexpr功能的情况下,“服从ODR”是什么意思? - What means “obey ODR” in case of inline and constexpr function? 关于静态模板化constexpr的clang警告(未定义内联函数) - Clang warning about static templated constexpr (inline function is not defined) 在内联函数的定义中使用 constexpr 变量时可能的 ODR 违规(在 C++14 中) - Possible ODR-violations when using a constexpr variable in the definition of an inline function (in C++14) 由于 header 中的匿名命名空间导致 ODR 违规 - ODR violation due to anonymous namespace in header constexpr和ODR - constexpr and ODR 模板功能中的特定类型具有不同的行为 - Have different behavior for specific type in a template function 标头中的“const”和“constexpr”变量是否应为“内联”以防止违反 ODR? - Should `const` and `constexpr` variables in headers be `inline` to prevent ODR violations? constexpr函数必须有一个参数值? - constexpr function must have one argument value?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM