Conditional compilation of templates

前端 未结 2 1586
天命终不由人
天命终不由人 2020-12-22 05:00

I am trying to get static_assert to help me avoid null pointers in C++11.

The problem seems to be that C++11 require the compiler to compile templates even if they a

2条回答
  •  春和景丽
    2020-12-22 05:44

    The standard permits, but does not require, compilers to diagnose templates for which no valid instantiation can be generated. This can range from simple syntax errors to your example of a constant false expression in a static_assert. §14.6 [temp.res]/p8:

    If no valid specialization can be generated for a template, and that template is not instantiated, the template is ill-formed, no diagnostic required.

    I'm rather baffled by all this SFINAE machinery, though. A simple

    template
    T* create_if_constructible(Us... args) { return new T(args...); }
    

    already refuses to compile if T is not constructible from the parameter given, so I'm not sure how this complex circumlocution will help you "avoid null pointers".

    Regardless, a simple way to make choosing the second function template a compile-time error is to explicitly delete it.

    template
    std::enable_if_t< std::is_constructible::value == false, T * >
    create_if_constructible(Us... args) = delete;
    

    Alternatively, if you are partial to static_asserts, perhaps because of the custom error message, you must ensure that there is theoretically a way to generate a valid instantiation of your template. That means that 1) what you are static_asserting on must depend on a template argument, and 2) there must be theoretically a way for the condition to be true. A simple way is to use an auxiliary template:

    template class always_false : std::false_type {};
    
    template
    std::enable_if_t< std::is_constructible::value == false, T * >
    create_if_constructible(Us... args) { 
       static_assert( always_false::value, "Class T constructor does not match argument list.");
       return nullptr; 
    }
    

    The key point here is that the compiler cannot assume that always_false::value is always false because it is always possible that there's a specialization later that sets it to true, and so it is not allowed to reject this at template definition time.

提交回复
热议问题