Question: For a given template, for example `std::string`, can the template detect if the instance of `string` being declared/defined is a constant. (Note: I am not asking about template arguments.)

```
std::string mutable_string("a string that may possibly be changed");

```

versus

```
const std::string immutable_string("a string that will not change);

```

If this is possible, the template could allocate exactly the amount of heap storage for the string literal supplied to the constructor. Furthermore, non-const, non-ctor/dtor methods' code generation could be elided (unless some translation unit defines a non-const string).

I was hoping for something semantically similar to:

```
is_constant<std::string>(*this)::value

```

Is it possible to compare the type of the instance to that type with the const qualifier stripped?

**Update/Clarification**: Extending the `std::string` example, could a template specialization for `const std::string` be able to declare inspectors as `constexpr` (e.g. `size()`, `capacity()`?

Answer: 
If I get you right:

```
#include <iostream>

template <typename T>
inline constexpr bool is_constant(T&) {
    return false;
}

template <typename T>
inline constexpr bool is_constant(const T&) {
    return true;
}

template <bool Value>
void print() {
    std::cout << (Value ? "true " : "false ");
}

struct X {
    void a() { print<is_constant(*this)>(); }
    void b() const { print<is_constant(*this)>(); }
};

int main() {
    X x;
    // false
    x.a();
    // true
    x.b();
    std::cout << '\n';
    return 0;
}

```

However, if you want to detect if an object will be const qualified, it is impossible - a constructor is never const.
No, you cannot detect whether the object being constructed will be marked `const` or not. If your concern is to provide exact memory allocation, just do, it will be fine. If the string is not const then it will grow as needed when needed.

Regarding the code generation, members of templates are usually generated on demand, so if they are not used, they won't be generated, so there is no win there. The *usually* is because this is not the case in explicit instantiations, and in this particular case your implementation might be doing an explicit instantiation for performance reasons (compiler time), since for the common instantiations of `basic_string` (`char`, `wchar_t`) the vendor can provide the implementation already in binary form in a linked library.